diff options
Diffstat (limited to 'include/linux')
62 files changed, 4215 insertions, 81 deletions
diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h index d936409520f8..ebd37eb1462b 100644 --- a/include/linux/clk-provider.h +++ b/include/linux/clk-provider.h @@ -14,6 +14,7 @@ #include <linux/clk.h> #include <linux/io.h> #include <linux/of.h> +typedef void (*of_clk_init_cb_t)(struct device_node *); #ifdef CONFIG_COMMON_CLK @@ -563,7 +564,6 @@ unsigned long __clk_round_rate(struct clk *clk, unsigned long rate); struct of_device_id; -typedef void (*of_clk_init_cb_t)(struct device_node *); struct clk_onecell_data { struct clk **clks; diff --git a/include/linux/clk.h b/include/linux/clk.h index c7f258a81761..a4c1834bbce0 100644 --- a/include/linux/clk.h +++ b/include/linux/clk.h @@ -424,7 +424,7 @@ int clk_add_alias(const char *alias, const char *alias_dev_name, char *id, struct device_node; struct of_phandle_args; -#if defined(CONFIG_OF) && defined(CONFIG_COMMON_CLK) +#if defined(CONFIG_OF) struct clk *of_clk_get(struct device_node *np, int index); struct clk *of_clk_get_by_name(struct device_node *np, const char *name); struct clk *of_clk_get_from_provider(struct of_phandle_args *clkspec); diff --git a/include/linux/clk/msm-clk-provider.h b/include/linux/clk/msm-clk-provider.h new file mode 100644 index 000000000000..719bfd8cc22c --- /dev/null +++ b/include/linux/clk/msm-clk-provider.h @@ -0,0 +1,242 @@ +/* + * Copyright (C) 2007 Google, Inc. + * Copyright (c) 2007-2013, The Linux Foundation. All rights reserved. + * + * 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. + * + */ + +#ifndef __MSM_CLK_PROVIDER_H +#define __MSM_CLK_PROVIDER_H + +#include <linux/types.h> +#include <linux/err.h> +#include <linux/list.h> +#include <linux/clkdev.h> +#include <linux/of.h> +#include <linux/device.h> +#include <linux/spinlock.h> +#include <linux/mutex.h> +#include <linux/regulator/consumer.h> +#include <linux/seq_file.h> +#include <linux/clk/msm-clk.h> + +/* + * Bit manipulation macros + */ +#define BM(msb, lsb) (((((uint32_t)-1) << (31-msb)) >> (31-msb+lsb)) << lsb) +#define BVAL(msb, lsb, val) (((val) << lsb) & BM(msb, lsb)) + +/* + * Halt/Status Checking Mode Macros + */ +#define HALT 0 /* Bit pol: 1 = halted */ +#define NOCHECK 1 /* No bit to check, do nothing */ +#define HALT_VOTED 2 /* Bit pol: 1 = halted; delay on disable */ +#define ENABLE 3 /* Bit pol: 1 = running */ +#define ENABLE_VOTED 4 /* Bit pol: 1 = running; delay on disable */ +#define DELAY 5 /* No bit to check, just delay */ + +struct clk_register_data { + char *name; + u32 offset; +}; +#ifdef CONFIG_DEBUG_FS +void clk_debug_print_hw(struct clk *clk, struct seq_file *f); +#else +static inline void clk_debug_print_hw(struct clk *clk, struct seq_file *f) {} +#endif + +#define CLK_WARN(clk, cond, fmt, ...) do { \ + clk_debug_print_hw(clk, NULL); \ + WARN(cond, "%s: " fmt, (clk)->dbg_name, ##__VA_ARGS__); \ +} while (0) + +/** + * struct clk_vdd_class - Voltage scaling class + * @class_name: name of the class + * @regulator: array of regulators. + * @num_regulators: size of regulator array. Standard regulator APIs will be + used if this field > 0. + * @set_vdd: function to call when applying a new voltage setting. + * @vdd_uv: sorted 2D array of legal voltage settings. Indexed by level, then + regulator. + * @vdd_ua: sorted 2D array of legal cureent settings. Indexed by level, then + regulator. Optional parameter. + * @level_votes: array of votes for each level. + * @num_levels: specifies the size of level_votes array. + * @cur_level: the currently set voltage level + * @lock: lock to protect this struct + */ +struct clk_vdd_class { + const char *class_name; + struct regulator **regulator; + int num_regulators; + int (*set_vdd)(struct clk_vdd_class *v_class, int level); + int *vdd_uv; + int *vdd_ua; + int *level_votes; + int num_levels; + unsigned long cur_level; + struct mutex lock; +}; + +#define DEFINE_VDD_CLASS(_name, _set_vdd, _num_levels) \ + struct clk_vdd_class _name = { \ + .class_name = #_name, \ + .set_vdd = _set_vdd, \ + .level_votes = (int [_num_levels]) {}, \ + .num_levels = _num_levels, \ + .cur_level = _num_levels, \ + .lock = __MUTEX_INITIALIZER(_name.lock) \ + } + +#define DEFINE_VDD_REGULATORS(_name, _num_levels, _num_regulators, _vdd_uv, \ + _vdd_ua) \ + struct clk_vdd_class _name = { \ + .class_name = #_name, \ + .vdd_uv = _vdd_uv, \ + .vdd_ua = _vdd_ua, \ + .regulator = (struct regulator * [_num_regulators]) {}, \ + .num_regulators = _num_regulators, \ + .level_votes = (int [_num_levels]) {}, \ + .num_levels = _num_levels, \ + .cur_level = _num_levels, \ + .lock = __MUTEX_INITIALIZER(_name.lock) \ + } + +#define DEFINE_VDD_REGS_INIT(_name, _num_regulators) \ + struct clk_vdd_class _name = { \ + .class_name = #_name, \ + .regulator = (struct regulator * [_num_regulators]) {}, \ + .num_regulators = _num_regulators, \ + .lock = __MUTEX_INITIALIZER(_name.lock) \ + } + +enum handoff { + HANDOFF_ENABLED_CLK, + HANDOFF_DISABLED_CLK, +}; + +struct clk_ops { + int (*prepare)(struct clk *clk); + int (*enable)(struct clk *clk); + void (*disable)(struct clk *clk); + void (*unprepare)(struct clk *clk); + void (*enable_hwcg)(struct clk *clk); + void (*disable_hwcg)(struct clk *clk); + int (*in_hwcg_mode)(struct clk *clk); + enum handoff (*handoff)(struct clk *clk); + int (*reset)(struct clk *clk, enum clk_reset_action action); + int (*pre_set_rate)(struct clk *clk, unsigned long new_rate); + int (*set_rate)(struct clk *clk, unsigned long rate); + void (*post_set_rate)(struct clk *clk, unsigned long old_rate); + int (*set_max_rate)(struct clk *clk, unsigned long rate); + int (*set_flags)(struct clk *clk, unsigned flags); + unsigned long (*get_rate)(struct clk *clk); + long (*list_rate)(struct clk *clk, unsigned n); + int (*is_enabled)(struct clk *clk); + long (*round_rate)(struct clk *clk, unsigned long rate); + int (*set_parent)(struct clk *clk, struct clk *parent); + struct clk *(*get_parent)(struct clk *clk); + bool (*is_local)(struct clk *clk); + void __iomem *(*list_registers)(struct clk *clk, int n, + struct clk_register_data **regs, u32 *size); +}; + +/** + * struct clk + * @prepare_count: prepare refcount + * @prepare_lock: protects clk_prepare()/clk_unprepare() path and @prepare_count + * @count: enable refcount + * @lock: protects clk_enable()/clk_disable() path and @count + * @depends: non-direct parent of clock to enable when this clock is enabled + * @vdd_class: voltage scaling requirement class + * @fmax: maximum frequency in Hz supported at each voltage level + * @parent: the current source of this clock + */ +struct clk { + uint32_t flags; + struct clk_ops *ops; + const char *dbg_name; + struct clk *depends; + struct clk_vdd_class *vdd_class; + unsigned long *fmax; + int num_fmax; + unsigned long rate; + struct clk *parent; + + struct list_head children; + struct list_head siblings; + + unsigned count; + spinlock_t lock; + unsigned prepare_count; + struct mutex prepare_lock; + + struct dentry *clk_dir; +}; + +#define CLK_INIT(name) \ + .lock = __SPIN_LOCK_UNLOCKED((name).lock), \ + .prepare_lock = __MUTEX_INITIALIZER((name).prepare_lock), \ + .children = LIST_HEAD_INIT((name).children), \ + .siblings = LIST_HEAD_INIT((name).siblings) + +int vote_vdd_level(struct clk_vdd_class *vdd_class, int level); +int unvote_vdd_level(struct clk_vdd_class *vdd_class, int level); +int __clk_pre_reparent(struct clk *c, struct clk *new, unsigned long *flags); +void __clk_post_reparent(struct clk *c, struct clk *old, unsigned long *flags); + +/* Register clocks with the MSM clock driver */ +int msm_clock_register(struct clk_lookup *table, size_t size); +int of_msm_clock_register(struct device_node *np, struct clk_lookup *table, + size_t size); + +extern struct clk dummy_clk; +extern struct clk_ops clk_ops_dummy; + +#define CLK_DUMMY(clk_name, clk_id, clk_dev, flags) { \ + .con_id = clk_name, \ + .dev_id = clk_dev, \ + .clk = &dummy_clk, \ + } + +#define DEFINE_CLK_DUMMY(name, _rate) \ + static struct fixed_clk name = { \ + .c = { \ + .dbg_name = #name, \ + .rate = _rate, \ + .ops = &clk_ops_dummy, \ + CLK_INIT(name.c), \ + }, \ + }; + +#define CLK_LOOKUP(con, c, dev) { .con_id = con, .clk = &c, .dev_id = dev } +#define CLK_LOOKUP_OF(con, _c, dev) { .con_id = con, .clk = &(&_c)->c, \ + .dev_id = dev, .of_idx = clk_##_c } +#define CLK_LIST(_c) { .clk = &(&_c)->c, .of_idx = clk_##_c } + +static inline bool is_better_rate(unsigned long req, unsigned long best, + unsigned long new) +{ + if (IS_ERR_VALUE(new)) + return false; + + return (req <= new && new < best) || (best < req && best < new); +} + +extern int of_clk_add_provider(struct device_node *np, + struct clk *(*clk_src_get)(struct of_phandle_args *args, + void *data), + void *data); +extern void of_clk_del_provider(struct device_node *np); + +#endif diff --git a/include/linux/clk/msm-clk.h b/include/linux/clk/msm-clk.h new file mode 100644 index 000000000000..59365027ff68 --- /dev/null +++ b/include/linux/clk/msm-clk.h @@ -0,0 +1,48 @@ +/* Copyright (c) 2009, 2012-2013 The Linux Foundation. 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 version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#ifndef __MACH_CLK_H +#define __MACH_CLK_H + +#define CLKFLAG_INVERT 0x00000001 +#define CLKFLAG_NOINVERT 0x00000002 +#define CLKFLAG_NONEST 0x00000004 +#define CLKFLAG_NORESET 0x00000008 +#define CLKFLAG_RETAIN_PERIPH 0x00000010 +#define CLKFLAG_NORETAIN_PERIPH 0x00000020 +#define CLKFLAG_RETAIN_MEM 0x00000040 +#define CLKFLAG_NORETAIN_MEM 0x00000080 +#define CLKFLAG_SKIP_HANDOFF 0x00000100 +#define CLKFLAG_MIN 0x00000400 +#define CLKFLAG_MAX 0x00000800 +#define CLKFLAG_INIT_DONE 0x00001000 +#define CLKFLAG_INIT_ERR 0x00002000 +#define CLKFLAG_NO_RATE_CACHE 0x00004000 +#define CLKFLAG_MEASURE 0x00008000 + +struct clk_lookup; +struct clk; + +enum clk_reset_action { + CLK_RESET_DEASSERT = 0, + CLK_RESET_ASSERT = 1 +}; + +/* Rate is maximum clock rate in Hz */ +int clk_set_max_rate(struct clk *clk, unsigned long rate); + +/* Assert/Deassert reset to a hardware block associated with a clock */ +int clk_reset(struct clk *clk, enum clk_reset_action action); + +/* Set clock-specific configuration parameters */ +int clk_set_flags(struct clk *clk, unsigned long flags); + +#endif diff --git a/include/linux/clk/msm-clock-generic.h b/include/linux/clk/msm-clock-generic.h new file mode 100644 index 000000000000..efb4730d5042 --- /dev/null +++ b/include/linux/clk/msm-clock-generic.h @@ -0,0 +1,266 @@ +/* + * Copyright (c) 2013-2014, The Linux Foundation. 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 version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef __MSM_CLOCK_GENERIC_H +#define __MSM_CLOCK_GENERIC_H + +#include <linux/clk/msm-clk-provider.h> + +/** + * struct fixed_clk - fixed rate clock + * @c: clk + */ +struct fixed_clk { + struct clk c; +}; + +/* ==================== Mux clock ==================== */ + +struct clk_src { + struct clk *src; + int sel; +}; + +struct mux_clk; + +struct clk_mux_ops { + int (*set_mux_sel)(struct mux_clk *clk, int sel); + int (*get_mux_sel)(struct mux_clk *clk); + + /* Optional */ + bool (*is_enabled)(struct mux_clk *clk); + int (*enable)(struct mux_clk *clk); + void (*disable)(struct mux_clk *clk); + void __iomem *(*list_registers)(struct mux_clk *clk, int n, + struct clk_register_data **regs, u32 *size); +}; + +#define MUX_SRC_LIST(...) \ + .parents = (struct clk_src[]){__VA_ARGS__}, \ + .num_parents = ARRAY_SIZE(((struct clk_src[]){__VA_ARGS__})) + +#define MUX_REC_SRC_LIST(...) \ + .rec_parents = (struct clk * []){__VA_ARGS__}, \ + .num_rec_parents = ARRAY_SIZE(((struct clk * []){__VA_ARGS__})) + +struct mux_clk { + /* Parents in decreasing order of preference for obtaining rates. */ + struct clk_src *parents; + int num_parents; + /* Recursively search for the requested parent in rec_parents. */ + struct clk **rec_parents; + int num_rec_parents; + struct clk *safe_parent; + int safe_sel; + struct clk_mux_ops *ops; + + /* Fields not used by helper function. */ + void *const __iomem *base; + u32 offset; + u32 en_offset; + int en_reg; + u32 mask; + u32 shift; + u32 en_mask; + void *priv; + + struct clk c; +}; + +static inline struct mux_clk *to_mux_clk(struct clk *c) +{ + return container_of(c, struct mux_clk, c); +} + +int parent_to_src_sel(struct clk_src *parents, int num_parents, struct clk *p); + +extern struct clk_ops clk_ops_gen_mux; + +/* ==================== Divider clock ==================== */ + +struct div_clk; + +struct clk_div_ops { + int (*set_div)(struct div_clk *clk, int div); + int (*get_div)(struct div_clk *clk); + bool (*is_enabled)(struct div_clk *clk); + int (*enable)(struct div_clk *clk); + void (*disable)(struct div_clk *clk); + void __iomem *(*list_registers)(struct div_clk *clk, int n, + struct clk_register_data **regs, u32 *size); +}; + +struct div_data { + unsigned int div; + unsigned int min_div; + unsigned int max_div; + unsigned long rate_margin; + /* + * Indicate whether this divider clock supports half-interger divider. + * If it is, all the min_div and max_div have been doubled. It means + * they are 2*N. + */ + bool is_half_divider; +}; + +struct div_clk { + struct div_data data; + + /* Optional */ + struct clk_div_ops *ops; + + /* Fields not used by helper function. */ + void *const __iomem *base; + u32 offset; + u32 mask; + u32 shift; + u32 en_mask; + void *priv; + struct clk c; +}; + +static inline struct div_clk *to_div_clk(struct clk *c) +{ + return container_of(c, struct div_clk, c); +} + +extern struct clk_ops clk_ops_div; +extern struct clk_ops clk_ops_slave_div; + +struct ext_clk { + struct clk c; +}; + +long parent_round_rate(struct clk *c, unsigned long rate); +unsigned long parent_get_rate(struct clk *c); +extern struct clk_ops clk_ops_ext; + +#define DEFINE_FIXED_DIV_CLK(clk_name, _div, _parent) \ +static struct div_clk clk_name = { \ + .data = { \ + .max_div = _div, \ + .min_div = _div, \ + .div = _div, \ + }, \ + .c = { \ + .parent = _parent, \ + .dbg_name = #clk_name, \ + .ops = &clk_ops_div, \ + CLK_INIT(clk_name.c), \ + } \ +} + +#define DEFINE_FIXED_SLAVE_DIV_CLK(clk_name, _div, _parent) \ +static struct div_clk clk_name = { \ + .data = { \ + .max_div = _div, \ + .min_div = _div, \ + .div = _div, \ + }, \ + .c = { \ + .parent = _parent, \ + .dbg_name = #clk_name, \ + .ops = &clk_ops_slave_div, \ + CLK_INIT(clk_name.c), \ + } \ +} + +#define DEFINE_EXT_CLK(clk_name, _parent) \ +static struct ext_clk clk_name = { \ + .c = { \ + .parent = _parent, \ + .dbg_name = #clk_name, \ + .ops = &clk_ops_ext, \ + CLK_INIT(clk_name.c), \ + } \ +} + +/* ==================== Mux Div clock ==================== */ + +struct mux_div_clk; + +/* + * struct mux_div_ops + * the enable and disable ops are optional. + */ + +struct mux_div_ops { + int (*set_src_div)(struct mux_div_clk *, u32 src_sel, u32 div); + void (*get_src_div)(struct mux_div_clk *, u32 *src_sel, u32 *div); + int (*enable)(struct mux_div_clk *); + void (*disable)(struct mux_div_clk *); + bool (*is_enabled)(struct mux_div_clk *); + void __iomem *(*list_registers)(struct mux_div_clk *md, int n, + struct clk_register_data **regs, u32 *size); +}; + +/* + * struct mux_div_clk - combined mux/divider clock + * @priv + parameters needed by ops + * @safe_freq + when switching rates from A to B, the mux div clock will + instead switch from A -> safe_freq -> B. This allows the + mux_div clock to change rates while enabled, even if this + behavior is not supported by the parent clocks. + + If changing the rate of parent A also causes the rate of + parent B to change, then safe_freq must be defined. + + safe_freq is expected to have a source clock which is always + on and runs at only one rate. + * @parents + list of parents and mux indicies + * @ops + function pointers for hw specific operations + * @src_sel + the mux index which will be used if the clock is enabled. + */ + +struct mux_div_clk { + /* Required parameters */ + struct mux_div_ops *ops; + struct div_data data; + struct clk_src *parents; + u32 num_parents; + + struct clk c; + + /* Internal */ + u32 src_sel; + + /* Optional parameters */ + void *priv; + void __iomem *base; + u32 div_mask; + u32 div_offset; + u32 div_shift; + u32 src_mask; + u32 src_offset; + u32 src_shift; + u32 en_mask; + u32 en_offset; + + u32 safe_div; + struct clk *safe_parent; + unsigned long safe_freq; +}; + +static inline struct mux_div_clk *to_mux_div_clk(struct clk *clk) +{ + return container_of(clk, struct mux_div_clk, c); +} + +extern struct clk_ops clk_ops_mux_div_clk; + +#endif diff --git a/include/linux/clkdev.h b/include/linux/clkdev.h index 94bad77eeb4a..4a6ec35c3571 100644 --- a/include/linux/clkdev.h +++ b/include/linux/clkdev.h @@ -21,6 +21,7 @@ struct clk_lookup { struct list_head node; const char *dev_id; const char *con_id; + int of_idx; struct clk *clk; }; diff --git a/include/linux/cpu.h b/include/linux/cpu.h index 4260e8594bd7..e951904ff4e2 100644 --- a/include/linux/cpu.h +++ b/include/linux/cpu.h @@ -271,4 +271,11 @@ void arch_cpu_idle_enter(void); void arch_cpu_idle_exit(void); void arch_cpu_idle_dead(void); +#define IDLE_START 1 +#define IDLE_END 2 + +void idle_notifier_register(struct notifier_block *n); +void idle_notifier_unregister(struct notifier_block *n); +void idle_notifier_call_chain(unsigned long val); + #endif /* _LINUX_CPU_H_ */ diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h index 4d078cebafd2..2697bd8473ac 100644 --- a/include/linux/cpufreq.h +++ b/include/linux/cpufreq.h @@ -500,6 +500,7 @@ extern struct cpufreq_governor cpufreq_gov_conservative; struct cpufreq_frequency_table { unsigned int flags; unsigned int driver_data; /* driver specific data, not used by core */ + unsigned int index; /* any */ unsigned int frequency; /* kHz - doesn't need to be in ascending * order */ }; diff --git a/include/linux/devfreq.h b/include/linux/devfreq.h index ce447f0f1bad..b6f3cadb9ce1 100644 --- a/include/linux/devfreq.h +++ b/include/linux/devfreq.h @@ -52,6 +52,24 @@ struct devfreq_dev_status { */ #define DEVFREQ_FLAG_LEAST_UPPER_BOUND 0x1 +#define DEVFREQ_FLAG_FAST_HINT 0x2 +#define DEVFREQ_FLAG_SLOW_HINT 0x4 +#define DEVFREQ_FLAG_WAKEUP_MAXFREQ 0x8 + +/** + * struct devfreq_governor_data - mapping to per device governor data + * @name: The name of the governor. + * @data: Private data for the governor. + * + * Devices may pass in an array of this structure to allow governors + * to get the correct data pointer when they are enabled after + * the devfreq_add_device() call. + */ +struct devfreq_governor_data { + const char *name; + void *data; +}; + /** * struct devfreq_dev_profile - Devfreq's user device profile * @initial_freq: The operating frequency when devfreq_add_device() is @@ -75,6 +93,11 @@ struct devfreq_dev_status { * this is the time to unregister it. * @freq_table: Optional list of frequencies to support statistics. * @max_state: The size of freq_table. + * @governor_data: Optional array of private data for governors. + * This is used to set devfreq->data correctly + * when a governor is enabled via sysfs or other + * mechanisms after the devfreq_add_device() call. + * @num_governor_data: Number of elements in governor_data. */ struct devfreq_dev_profile { unsigned long initial_freq; @@ -88,6 +111,8 @@ struct devfreq_dev_profile { unsigned int *freq_table; unsigned int max_state; + const struct devfreq_governor_data *governor_data; + unsigned int num_governor_data; }; /** @@ -111,7 +136,8 @@ struct devfreq_governor { struct list_head node; const char name[DEVFREQ_NAME_LEN]; - int (*get_target_freq)(struct devfreq *this, unsigned long *freq); + int (*get_target_freq)(struct devfreq *this, unsigned long *freq, + u32 *flag); int (*event_handler)(struct devfreq *devfreq, unsigned int event, void *data); }; @@ -214,6 +240,9 @@ extern void devm_devfreq_unregister_opp_notifier(struct device *dev, * the governor may consider slowing the frequency down. * Specify 0 to use the default. Valid value = 0 to 100. * downdifferential < upthreshold must hold. + * @simple_scaling: Setting this flag will scale the clocks up only if the + * load is above @upthreshold and will scale the clocks + * down only if the load is below @downdifferential. * * If the fed devfreq_simple_ondemand_data pointer is NULL to the governor, * the governor uses the default values. @@ -221,6 +250,7 @@ extern void devm_devfreq_unregister_opp_notifier(struct device *dev, struct devfreq_simple_ondemand_data { unsigned int upthreshold; unsigned int downdifferential; + unsigned int simple_scaling; }; #endif diff --git a/include/linux/dma-attrs.h b/include/linux/dma-attrs.h index c8e1831d7572..eb1b9d727f39 100644 --- a/include/linux/dma-attrs.h +++ b/include/linux/dma-attrs.h @@ -18,6 +18,8 @@ enum dma_attr { DMA_ATTR_NO_KERNEL_MAPPING, DMA_ATTR_SKIP_CPU_SYNC, DMA_ATTR_FORCE_CONTIGUOUS, + DMA_ATTR_STRONGLY_ORDERED, + DMA_ATTR_SKIP_ZEROING, DMA_ATTR_MAX, }; diff --git a/include/linux/esoc_client.h b/include/linux/esoc_client.h new file mode 100644 index 000000000000..5da1b6dc6193 --- /dev/null +++ b/include/linux/esoc_client.h @@ -0,0 +1,52 @@ +/* Copyright (c) 2014, The Linux Foundation. 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 version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#ifndef __ESOC_CLIENT_H_ +#define __ESOC_CLIENT_H_ + +#include <linux/esoc_ctrl.h> +#include <linux/notifier.h> + +/* + * struct esoc_desc: Describes an external soc + * @name: external soc name + * @priv: private data for external soc + */ +struct esoc_desc { + const char *name; + const char *link; + void *priv; +}; + +#ifdef CONFIG_ESOC_CLIENT +/* Can return probe deferral */ +struct esoc_desc *devm_register_esoc_client(struct device *dev, + const char *name); +void devm_unregister_esoc_client(struct device *dev, + struct esoc_desc *esoc_desc); +int esoc_register_client_notifier(struct notifier_block *nb); +#else +static inline struct esoc_desc *devm_register_esoc_client(struct device *dev, + const char *name) +{ + return NULL; +} +static inline void devm_unregister_esoc_client(struct device *dev, + struct esoc_desc *esoc_desc) +{ + return; +} +static inline int esoc_register_client_notifier(struct notifier_block *nb) +{ + return -EIO; +} +#endif +#endif diff --git a/include/linux/gfp.h b/include/linux/gfp.h index b840e3b2770d..6711da990d67 100644 --- a/include/linux/gfp.h +++ b/include/linux/gfp.h @@ -34,6 +34,7 @@ struct vm_area_struct; #define ___GFP_NO_KSWAPD 0x400000u #define ___GFP_OTHER_NODE 0x800000u #define ___GFP_WRITE 0x1000000u +#define ___GFP_CMA 0x2000000u /* If the above are modified, __GFP_BITS_SHIFT may need updating */ /* @@ -49,7 +50,9 @@ struct vm_area_struct; #define __GFP_HIGHMEM ((__force gfp_t)___GFP_HIGHMEM) #define __GFP_DMA32 ((__force gfp_t)___GFP_DMA32) #define __GFP_MOVABLE ((__force gfp_t)___GFP_MOVABLE) /* Page is movable */ -#define GFP_ZONEMASK (__GFP_DMA|__GFP_HIGHMEM|__GFP_DMA32|__GFP_MOVABLE) +#define __GFP_CMA ((__force gfp_t)___GFP_CMA) +#define GFP_ZONEMASK (__GFP_DMA|__GFP_HIGHMEM|__GFP_DMA32|__GFP_MOVABLE| \ + __GFP_CMA) /* * Action modifiers - doesn't change the zoning * @@ -97,7 +100,7 @@ struct vm_area_struct; */ #define __GFP_NOTRACK_FALSE_POSITIVE (__GFP_NOTRACK) -#define __GFP_BITS_SHIFT 25 /* Room for N __GFP_FOO bits */ +#define __GFP_BITS_SHIFT 26 /* Room for N __GFP_FOO bits */ #define __GFP_BITS_MASK ((__force gfp_t)((1 << __GFP_BITS_SHIFT) - 1)) /* This equals 0, but use constants in case they ever change */ @@ -128,7 +131,7 @@ struct vm_area_struct; #endif /* This mask makes up all the page movable related flags */ -#define GFP_MOVABLE_MASK (__GFP_RECLAIMABLE|__GFP_MOVABLE) +#define GFP_MOVABLE_MASK (__GFP_RECLAIMABLE|__GFP_MOVABLE|__GFP_CMA) /* Control page allocator reclaim behavior */ #define GFP_RECLAIM_MASK (__GFP_WAIT|__GFP_HIGH|__GFP_IO|__GFP_FS|\ @@ -161,8 +164,14 @@ static inline int gfpflags_to_migratetype(const gfp_t gfp_flags) return MIGRATE_UNMOVABLE; /* Group based on mobility */ +#ifndef CONFIG_CMA return (((gfp_flags & __GFP_MOVABLE) != 0) << 1) | ((gfp_flags & __GFP_RECLAIMABLE) != 0); +#else + return (((gfp_flags & __GFP_MOVABLE) != 0) << 1) | + (((gfp_flags & __GFP_CMA) != 0) << 1) | + ((gfp_flags & __GFP_RECLAIMABLE) != 0); +#endif } #ifdef CONFIG_HIGHMEM diff --git a/include/linux/hardirq.h b/include/linux/hardirq.h index cba442ec3c66..e70442c91d9f 100644 --- a/include/linux/hardirq.h +++ b/include/linux/hardirq.h @@ -11,6 +11,74 @@ extern void synchronize_irq(unsigned int irq); extern void synchronize_hardirq(unsigned int irq); +#define PREEMPT_OFFSET (1UL << PREEMPT_SHIFT) +#define SOFTIRQ_OFFSET (1UL << SOFTIRQ_SHIFT) +#define HARDIRQ_OFFSET (1UL << HARDIRQ_SHIFT) +#define NMI_OFFSET (1UL << NMI_SHIFT) + +#define SOFTIRQ_DISABLE_OFFSET (2 * SOFTIRQ_OFFSET) + +#ifndef PREEMPT_ACTIVE +#define PREEMPT_ACTIVE_BITS 1 +#define PREEMPT_ACTIVE_SHIFT (NMI_SHIFT + NMI_BITS) +#define PREEMPT_ACTIVE (__IRQ_MASK(PREEMPT_ACTIVE_BITS) << PREEMPT_ACTIVE_SHIFT) +#endif + +#if PREEMPT_ACTIVE < (1 << (NMI_SHIFT + NMI_BITS)) +#error PREEMPT_ACTIVE is too low! +#endif + +#define hardirq_count() (preempt_count() & HARDIRQ_MASK) +#define softirq_count() (preempt_count() & SOFTIRQ_MASK) +#define irq_count() (preempt_count() & (HARDIRQ_MASK | SOFTIRQ_MASK \ + | NMI_MASK)) + +/* + * Are we doing bottom half or hardware interrupt processing? + * Are we in a softirq context? Interrupt context? + * in_softirq - Are we currently processing softirq or have bh disabled? + * in_serving_softirq - Are we currently processing softirq? + */ +#define in_irq() (hardirq_count()) +#define in_softirq() (softirq_count()) +#define in_interrupt() (irq_count()) +#define in_serving_softirq() (softirq_count() & SOFTIRQ_OFFSET) + +/* + * Are we in NMI context? + */ +#define in_nmi() (preempt_count() & NMI_MASK) + +#if defined(CONFIG_PREEMPT_COUNT) +# define PREEMPT_CHECK_OFFSET 1 +#else +# define PREEMPT_CHECK_OFFSET 0 +#endif + +/* + * Are we running in atomic context? WARNING: this macro cannot + * always detect atomic context; in particular, it cannot know about + * held spinlocks in non-preemptible kernels. Thus it should not be + * used in the general case to determine whether sleeping is possible. + * Do not use in_atomic() in driver code. + */ +#define in_atomic() ((preempt_count() & ~PREEMPT_ACTIVE) != 0) + +/* + * Check whether we were atomic before we did preempt_disable(): + * (used by the scheduler, *after* releasing the kernel lock) + */ +#define in_atomic_preempt_off() \ + ((preempt_count() & ~PREEMPT_ACTIVE) != PREEMPT_CHECK_OFFSET) + +#ifdef CONFIG_PREEMPT_COUNT +# define preemptible() (preempt_count() == 0 && !irqs_disabled()) +#else +# define preemptible() 0 +#endif + +extern void synchronize_irq(unsigned int irq); + #if defined(CONFIG_TINY_RCU) static inline void rcu_nmi_enter(void) diff --git a/include/linux/highmem.h b/include/linux/highmem.h index 9286a46b7d69..bc4af51ce3e4 100644 --- a/include/linux/highmem.h +++ b/include/linux/highmem.h @@ -39,6 +39,12 @@ extern unsigned long totalhigh_pages; void kmap_flush_unused(void); +#ifdef CONFIG_ARCH_WANT_KMAP_ATOMIC_FLUSH +void kmap_atomic_flush_unused(void); +#else +static inline void kmap_atomic_flush_unused(void) { } +#endif + struct page *kmap_to_page(void *addr); #else /* CONFIG_HIGHMEM */ @@ -79,6 +85,7 @@ static inline void __kunmap_atomic(void *addr) #define kmap_atomic_to_page(ptr) virt_to_page(ptr) #define kmap_flush_unused() do {} while(0) +#define kmap_atomic_flush_unused() do {} while (0) #endif #endif /* CONFIG_HIGHMEM */ @@ -179,9 +186,24 @@ static inline struct page * alloc_zeroed_user_highpage_movable(struct vm_area_struct *vma, unsigned long vaddr) { +#ifndef CONFIG_CMA return __alloc_zeroed_user_highpage(__GFP_MOVABLE, vma, vaddr); +#else + return __alloc_zeroed_user_highpage(__GFP_MOVABLE|__GFP_CMA, vma, + vaddr); +#endif } +#ifdef CONFIG_CMA +static inline struct page * +alloc_zeroed_user_highpage_movable_cma(struct vm_area_struct *vma, + unsigned long vaddr) +{ + return __alloc_zeroed_user_highpage(__GFP_MOVABLE|__GFP_CMA, vma, + vaddr); +} +#endif + static inline void clear_highpage(struct page *page) { void *kaddr = kmap_atomic(page); diff --git a/include/linux/iopoll.h b/include/linux/iopoll.h new file mode 100644 index 000000000000..d085e03a2c45 --- /dev/null +++ b/include/linux/iopoll.h @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2012-2014 The Linux Foundation. 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 version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#ifndef _LINUX_IOPOLL_H +#define _LINUX_IOPOLL_H + +#include <linux/kernel.h> +#include <linux/types.h> +#include <linux/hrtimer.h> +#include <linux/delay.h> +#include <asm-generic/errno.h> +#include <asm/io.h> + +/** + * readl_poll_timeout - Periodically poll an address until a condition is met or a timeout occurs + * @addr: Address to poll + * @val: Variable to read the value into + * @cond: Break condition (usually involving @val) + * @sleep_us: Maximum time to sleep between reads in uS (0 tight-loops) + * @timeout_us: Timeout in uS, 0 means never timeout + * + * Returns 0 on success and -ETIMEDOUT upon a timeout. In either + * case, the last read value at @addr is stored in @val. Must not + * be called from atomic context if sleep_us or timeout_us are used. + */ +#define readl_poll_timeout(addr, val, cond, sleep_us, timeout_us) \ +({ \ + ktime_t timeout = ktime_add_us(ktime_get(), timeout_us); \ + might_sleep_if(timeout_us); \ + for (;;) { \ + (val) = readl(addr); \ + if (cond) \ + break; \ + if (timeout_us && ktime_compare(ktime_get(), timeout) > 0) { \ + (val) = readl(addr); \ + break; \ + } \ + if (sleep_us) \ + usleep_range(DIV_ROUND_UP(sleep_us, 4), sleep_us); \ + } \ + (cond) ? 0 : -ETIMEDOUT; \ +}) + +/** + * readl_poll_timeout_noirq - Periodically poll an address until a condition is met or a timeout occurs + * @addr: Address to poll + * @val: Variable to read the value into + * @cond: Break condition (usually involving @val) + * @max_reads: Maximum number of reads before giving up + * @time_between_us: Time to udelay() between successive reads + * + * Returns 0 on success and -ETIMEDOUT upon a timeout. + */ +#define readl_poll_timeout_noirq(addr, val, cond, max_reads, time_between_us) \ +({ \ + int count; \ + for (count = (max_reads); count > 0; count--) { \ + (val) = readl(addr); \ + if (cond) \ + break; \ + udelay(time_between_us); \ + } \ + (cond) ? 0 : -ETIMEDOUT; \ +}) + +/** + * readl_poll - Periodically poll an address until a condition is met + * @addr: Address to poll + * @val: Variable to read the value into + * @cond: Break condition (usually involving @val) + * @sleep_us: Maximum time to sleep between reads in uS (0 tight-loops) + * + * Must not be called from atomic context if sleep_us is used. + */ +#define readl_poll(addr, val, cond, sleep_us) \ + readl_poll_timeout(addr, val, cond, sleep_us, 0) + +/** + * readl_tight_poll_timeout - Tight-loop on an address until a condition is met or a timeout occurs + * @addr: Address to poll + * @val: Variable to read the value into + * @cond: Break condition (usually involving @val) + * @timeout_us: Timeout in uS, 0 means never timeout + * + * Returns 0 on success and -ETIMEDOUT upon a timeout. In either + * case, the last read value at @addr is stored in @val. Must not + * be called from atomic context if timeout_us is used. + */ +#define readl_tight_poll_timeout(addr, val, cond, timeout_us) \ + readl_poll_timeout(addr, val, cond, 0, timeout_us) + +/** + * readl_tight_poll - Tight-loop on an address until a condition is met + * @addr: Address to poll + * @val: Variable to read the value into + * @cond: Break condition (usually involving @val) + * + * May be called from atomic context. + */ +#define readl_tight_poll(addr, val, cond) \ + readl_poll_timeout(addr, val, cond, 0, 0) + +#endif /* _LINUX_IOPOLL_H */ diff --git a/include/linux/ipc_logging.h b/include/linux/ipc_logging.h new file mode 100644 index 000000000000..532452b133d8 --- /dev/null +++ b/include/linux/ipc_logging.h @@ -0,0 +1,265 @@ +/* Copyright (c) 2012-2013, The Linux Foundation. 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 version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _IPC_LOGGING_H +#define _IPC_LOGGING_H + +#include <linux/types.h> + +#define MAX_MSG_SIZE 255 + +enum { + TSV_TYPE_MSG_START = 1, + TSV_TYPE_SKB = TSV_TYPE_MSG_START, + TSV_TYPE_STRING, + TSV_TYPE_MSG_END = TSV_TYPE_STRING, +}; + +struct tsv_header { + unsigned char type; + unsigned char size; /* size of data field */ +}; + +struct encode_context { + struct tsv_header hdr; + char buff[MAX_MSG_SIZE]; + int offset; +}; + +struct decode_context { + int output_format; /* 0 = debugfs */ + char *buff; /* output buffer */ + int size; /* size of output buffer */ +}; + +#if defined(CONFIG_IPC_LOGGING) +/* + * ipc_log_context_create: Create a debug log context + * Should not be called from atomic context + * + * @max_num_pages: Number of pages of logging space required (max. 10) + * @mod_name : Name of the directory entry under DEBUGFS + * + * returns context id on success, NULL on failure + */ +void *ipc_log_context_create(int max_num_pages, const char *modname); + +/* + * msg_encode_start: Start encoding a log message + * + * @ectxt: Temporary storage to hold the encoded message + * @type: Root event type defined by the module which is logging + */ +void msg_encode_start(struct encode_context *ectxt, uint32_t type); + +/* + * tsv_timestamp_write: Writes the current timestamp count + * + * @ectxt: Context initialized by calling msg_encode_start() + */ +int tsv_timestamp_write(struct encode_context *ectxt); + +/* + * tsv_pointer_write: Writes a data pointer + * + * @ectxt: Context initialized by calling msg_encode_start() + * @pointer: Pointer value to write + */ +int tsv_pointer_write(struct encode_context *ectxt, void *pointer); + +/* + * tsv_int32_write: Writes a 32-bit integer value + * + * @ectxt: Context initialized by calling msg_encode_start() + * @n: Integer to write + */ +int tsv_int32_write(struct encode_context *ectxt, int32_t n); + +/* + * tsv_int32_write: Writes a 32-bit integer value + * + * @ectxt: Context initialized by calling msg_encode_start() + * @n: Integer to write + */ +int tsv_byte_array_write(struct encode_context *ectxt, + void *data, int data_size); + +/* + * msg_encode_end: Complete the message encode process + * + * @ectxt: Temporary storage which holds the encoded message + */ +void msg_encode_end(struct encode_context *ectxt); + +/* + * msg_encode_end: Complete the message encode process + * + * @ectxt: Temporary storage which holds the encoded message + */ +void ipc_log_write(void *ctxt, struct encode_context *ectxt); + +/* + * ipc_log_string: Helper function to log a string + * + * @ilctxt: Debug Log Context created using ipc_log_context_create() + * @fmt: Data specified using format specifiers + */ +int ipc_log_string(void *ilctxt, const char *fmt, ...) __printf(2, 3); + +/** + * ipc_log_extract - Reads and deserializes log + * + * @ilctxt: logging context + * @buff: buffer to receive the data + * @size: size of the buffer + * @returns: 0 if no data read; >0 number of bytes read; < 0 error + * + * If no data is available to be read, then the ilctxt::read_avail + * completion is reinitialized. This allows clients to block + * until new log data is save. + */ +int ipc_log_extract(void *ilctxt, char *buff, int size); + +/* + * Print a string to decode context. + * @dctxt Decode context + * @args printf args + */ +#define IPC_SPRINTF_DECODE(dctxt, args...) \ +do { \ + int i; \ + i = scnprintf(dctxt->buff, dctxt->size, args); \ + dctxt->buff += i; \ + dctxt->size -= i; \ +} while (0) + +/* + * tsv_timestamp_read: Reads a timestamp + * + * @ectxt: Context retrieved by reading from log space + * @dctxt: Temporary storage to hold the decoded message + * @format: Output format while dumping through DEBUGFS + */ +void tsv_timestamp_read(struct encode_context *ectxt, + struct decode_context *dctxt, const char *format); + +/* + * tsv_pointer_read: Reads a data pointer + * + * @ectxt: Context retrieved by reading from log space + * @dctxt: Temporary storage to hold the decoded message + * @format: Output format while dumping through DEBUGFS + */ +void tsv_pointer_read(struct encode_context *ectxt, + struct decode_context *dctxt, const char *format); + +/* + * tsv_int32_read: Reads a 32-bit integer value + * + * @ectxt: Context retrieved by reading from log space + * @dctxt: Temporary storage to hold the decoded message + * @format: Output format while dumping through DEBUGFS + */ +int32_t tsv_int32_read(struct encode_context *ectxt, + struct decode_context *dctxt, const char *format); + +/* + * tsv_int32_read: Reads a 32-bit integer value + * + * @ectxt: Context retrieved by reading from log space + * @dctxt: Temporary storage to hold the decoded message + * @format: Output format while dumping through DEBUGFS + */ +void tsv_byte_array_read(struct encode_context *ectxt, + struct decode_context *dctxt, const char *format); + +/* + * add_deserialization_func: Register a deserialization function to + * to unpack the subevents of a main event + * + * @ctxt: Debug log context to which the deserialization function has + * to be registered + * @type: Main/Root event, defined by the module which is logging, to + * which this deserialization function has to be registered. + * @dfune: Deserialization function to be registered + * + * return 0 on success, -ve value on FAILURE + */ +int add_deserialization_func(void *ctxt, int type, + void (*dfunc)(struct encode_context *, + struct decode_context *)); + +/* + * ipc_log_context_destroy: Destroy debug log context + * + * @ctxt: debug log context created by calling ipc_log_context_create API. + */ +int ipc_log_context_destroy(void *ctxt); + +#else + +static inline void *ipc_log_context_create(int max_num_pages, + const char *modname) +{ return NULL; } + +static inline void msg_encode_start(struct encode_context *ectxt, + uint32_t type) { } + +static inline int tsv_timestamp_write(struct encode_context *ectxt) +{ return -EINVAL; } + +static inline int tsv_pointer_write(struct encode_context *ectxt, void *pointer) +{ return -EINVAL; } + +static inline int tsv_int32_write(struct encode_context *ectxt, int32_t n) +{ return -EINVAL; } + +static inline int tsv_byte_array_write(struct encode_context *ectxt, + void *data, int data_size) +{ return -EINVAL; } + +static inline void msg_encode_end(struct encode_context *ectxt) { } + +static inline void ipc_log_write(void *ctxt, struct encode_context *ectxt) { } + +static inline int ipc_log_string(void *ilctxt, const char *fmt, ...) +{ return -EINVAL; } + +static inline int ipc_log_extract(void *ilctxt, char *buff, int size) +{ return -EINVAL; } + +#define IPC_SPRINTF_DECODE(dctxt, args...) do { } while (0) + +static inline void tsv_timestamp_read(struct encode_context *ectxt, + struct decode_context *dctxt, const char *format) { } + +static inline void tsv_pointer_read(struct encode_context *ectxt, + struct decode_context *dctxt, const char *format) { } + +static inline int32_t tsv_int32_read(struct encode_context *ectxt, + struct decode_context *dctxt, const char *format) +{ return 0; } + +static inline void tsv_byte_array_read(struct encode_context *ectxt, + struct decode_context *dctxt, const char *format) { } + +static inline int add_deserialization_func(void *ctxt, int type, + void (*dfunc)(struct encode_context *, + struct decode_context *)) +{ return 0; } + +static inline int ipc_log_context_destroy(void *ctxt) +{ return 0; } + +#endif + +#endif diff --git a/include/linux/ipc_router.h b/include/linux/ipc_router.h new file mode 100644 index 000000000000..ace57220116f --- /dev/null +++ b/include/linux/ipc_router.h @@ -0,0 +1,298 @@ +/* Copyright (c) 2012-2014, The Linux Foundation. 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 version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _IPC_ROUTER_H +#define _IPC_ROUTER_H + +#include <linux/types.h> +#include <linux/socket.h> +#include <linux/errno.h> +#include <linux/mm.h> +#include <linux/list.h> +#include <linux/pm.h> +#include <linux/msm_ipc.h> +#include <linux/device.h> + +/* Maximum Wakeup Source Name Size */ +#define MAX_WS_NAME_SZ 32 + +/** + * enum msm_ipc_router_event - Events that will be generated by IPC Router + */ +enum msm_ipc_router_event { + IPC_ROUTER_CTRL_CMD_DATA = 1, + IPC_ROUTER_CTRL_CMD_HELLO, + IPC_ROUTER_CTRL_CMD_BYE, + IPC_ROUTER_CTRL_CMD_NEW_SERVER, + IPC_ROUTER_CTRL_CMD_REMOVE_SERVER, + IPC_ROUTER_CTRL_CMD_REMOVE_CLIENT, + IPC_ROUTER_CTRL_CMD_RESUME_TX, +}; + +/** + * rr_control_msg - Control message structure + * @cmd: Command identifier for HELLO message in Version 1. + * @hello: Message structure for HELLO message in Version 2. + * @srv: Message structure for NEW_SERVER/REMOVE_SERVER events. + * @cli: Message structure for REMOVE_CLIENT event. + */ +union rr_control_msg { + uint32_t cmd; + struct { + uint32_t cmd; + uint32_t magic; + uint32_t capability; + } hello; + struct { + uint32_t cmd; + uint32_t service; + uint32_t instance; + uint32_t node_id; + uint32_t port_id; + } srv; + struct { + uint32_t cmd; + uint32_t node_id; + uint32_t port_id; + } cli; +}; + +struct comm_mode_info { + int mode; + void *xprt_info; +}; + +/** + * msm_ipc_port - Definition of IPC Router port + * @list: List(local/control ports) in which this port is present. + * @this_port: Contains port's node_id and port_id information. + * @port_name: Contains service & instance info if the port hosts a service. + * @type: Type of the port - Client, Service, Control or Security Config. + * @flags: Flags to identify the port state. + * @port_lock: Lock to protect access to the port information. + * @mode_info: Communication mode of the port owner. + * @port_rx_q: Receive queue where incoming messages are queued. + * @port_rx_q_lock_lhb3: Lock to protect access to the port's rx_q. + * @rx_ws_name: Name of the receive wakeup source. + * @port_rx_ws: Wakeup source to prevent suspend until the rx_q is empty. + * @port_rx_wait_q: Wait queue to wait for the incoming messages. + * @restart_state: Flag to hold the restart state information. + * @restart_lock: Lock to protect access to the restart_state. + * @restart_wait: Wait Queue to wait for any restart events. + * @endpoint: Contains the information related to user-space interface. + * @notify: Function to notify the incoming events on the port. + * @check_send_permissions: Function to check access control from this port. + * @num_tx: Number of packets transmitted. + * @num_rx: Number of packets received. + * @num_tx_bytes: Number of bytes transmitted. + * @num_rx_bytes: Number of bytes received. + * @priv: Private information registered by the port owner. + */ +struct msm_ipc_port { + struct list_head list; + + struct msm_ipc_port_addr this_port; + struct msm_ipc_port_name port_name; + uint32_t type; + unsigned flags; + spinlock_t port_lock; + struct comm_mode_info mode_info; + + struct list_head port_rx_q; + struct mutex port_rx_q_lock_lhb3; + char rx_ws_name[MAX_WS_NAME_SZ]; + struct wakeup_source port_rx_ws; + wait_queue_head_t port_rx_wait_q; + + int restart_state; + spinlock_t restart_lock; + wait_queue_head_t restart_wait; + + void *endpoint; + void (*notify)(unsigned event, void *oob_data, + size_t oob_data_len, void *priv); + int (*check_send_permissions)(void *data); + + uint32_t num_tx; + uint32_t num_rx; + unsigned long num_tx_bytes; + unsigned long num_rx_bytes; + void *priv; +}; + +#ifdef CONFIG_IPC_ROUTER +/** + * msm_ipc_router_create_port() - Create a IPC Router port/endpoint + * @notify: Callback function to notify any event on the port. + * @event: Event ID to be handled. + * @oob_data: Any out-of-band data associated with the event. + * @oob_data_len: Size of the out-of-band data, if valid. + * @priv: Private data registered during the port creation. + * @priv: Private info to be passed while the notification is generated. + * + * @return: Pointer to the port on success, NULL on error. + */ +struct msm_ipc_port *msm_ipc_router_create_port( + void (*notify)(unsigned event, void *oob_data, + size_t oob_data_len, void *priv), + void *priv); + +/** + * msm_ipc_router_bind_control_port() - Bind a port as a control port + * @port_ptr: Port which needs to be marked as a control port. + * + * @return: 0 on success, standard Linux error codes on error. + */ +int msm_ipc_router_bind_control_port(struct msm_ipc_port *port_ptr); + +/** + * msm_ipc_router_lookup_server_name() - Resolve server address + * @srv_name: Name<service:instance> of the server to be resolved. + * @srv_info: Buffer to hold the resolved address. + * @num_entries_in_array: Number of server info the buffer can hold. + * @lookup_mask: Mask to specify the range of instances to be resolved. + * + * @return: Number of server addresses resolved on success, < 0 on error. + */ +int msm_ipc_router_lookup_server_name(struct msm_ipc_port_name *srv_name, + struct msm_ipc_server_info *srv_info, + int num_entries_in_array, + uint32_t lookup_mask); + +/** + * msm_ipc_router_send_msg() - Send a message/packet + * @src: Sender's address/port. + * @dest: Destination address. + * @data: Pointer to the data to be sent. + * @data_len: Length of the data to be sent. + * + * @return: 0 on success, < 0 on error. + */ +int msm_ipc_router_send_msg(struct msm_ipc_port *src, + struct msm_ipc_addr *dest, + void *data, unsigned int data_len); + +/** + * msm_ipc_router_get_curr_pkt_size() - Get the packet size of the first + * packet in the rx queue + * @port_ptr: Port which owns the rx queue. + * + * @return: Returns the size of the first packet, if available. + * 0 if no packets available, < 0 on error. + */ +int msm_ipc_router_get_curr_pkt_size(struct msm_ipc_port *port_ptr); + +/** + * msm_ipc_router_read_msg() - Read a message/packet + * @port_ptr: Receiver's port/address. + * @data: Pointer containing the address of the received data. + * @src: Address of the sender/source. + * @len: Length of the data being read. + * + * @return: 0 on success, < 0 on error. + */ +int msm_ipc_router_read_msg(struct msm_ipc_port *port_ptr, + struct msm_ipc_addr *src, + unsigned char **data, + unsigned int *len); + +/** + * msm_ipc_router_close_port() - Close the port + * @port_ptr: Pointer to the port to be closed. + * + * @return: 0 on success, < 0 on error. + */ +int msm_ipc_router_close_port(struct msm_ipc_port *port_ptr); + +/** + * msm_ipc_router_register_server() - Register a service on a port + * @server_port: IPC Router port with which a service is registered. + * @name: Service name <service_id:instance_id> that gets registered. + * + * @return: 0 on success, standard Linux error codes on error. + */ +int msm_ipc_router_register_server(struct msm_ipc_port *server_port, + struct msm_ipc_addr *name); + +/** + * msm_ipc_router_unregister_server() - Unregister a service from a port + * @server_port: Port with with a service is already registered. + * + * @return: 0 on success, standard Linux error codes on error. + */ +int msm_ipc_router_unregister_server(struct msm_ipc_port *server_port); + +#else + +struct msm_ipc_port *msm_ipc_router_create_port( + void (*notify)(unsigned event, void *oob_data, + size_t oob_data_len, void *priv), + void *priv) +{ + return NULL; +} + +static inline int msm_ipc_router_bind_control_port( + struct msm_ipc_port *port_ptr) +{ + return -ENODEV; +} + +int msm_ipc_router_lookup_server_name(struct msm_ipc_port_name *srv_name, + struct msm_ipc_server_info *srv_info, + int num_entries_in_array, + uint32_t lookup_mask) +{ + return -ENODEV; +} + +int msm_ipc_router_send_msg(struct msm_ipc_port *src, + struct msm_ipc_addr *dest, + void *data, unsigned int data_len) +{ + return -ENODEV; +} + +int msm_ipc_router_get_curr_pkt_size(struct msm_ipc_port *port_ptr) +{ + return -ENODEV; +} + +int msm_ipc_router_read_msg(struct msm_ipc_port *port_ptr, + struct msm_ipc_addr *src, + unsigned char **data, + unsigned int *len) +{ + return -ENODEV; +} + +int msm_ipc_router_close_port(struct msm_ipc_port *port_ptr) +{ + return -ENODEV; +} + +static inline int msm_ipc_router_register_server( + struct msm_ipc_port *server_port, + struct msm_ipc_addr *name) +{ + return -ENODEV; +} + +static inline int msm_ipc_router_unregister_server( + struct msm_ipc_port *server_port) +{ + return -ENODEV; +} + +#endif + +#endif diff --git a/include/linux/irq.h b/include/linux/irq.h index d09ec7a1243e..58ccc28d6b46 100644 --- a/include/linux/irq.h +++ b/include/linux/irq.h @@ -309,6 +309,7 @@ static inline irq_hw_number_t irqd_to_hwirq(struct irq_data *d) * @irq_retrigger: resend an IRQ to the CPU * @irq_set_type: set the flow type (IRQ_TYPE_LEVEL/etc.) of an IRQ * @irq_set_wake: enable/disable power-management wake-on of an IRQ + * @irq_read_line: return the current value on the irq line * @irq_bus_lock: function to lock access to slow bus (i2c) chips * @irq_bus_sync_unlock:function to sync and unlock slow bus (i2c) chips * @irq_cpu_online: configure an interrupt source for a secondary CPU @@ -342,6 +343,7 @@ struct irq_chip { int (*irq_set_affinity)(struct irq_data *data, const struct cpumask *dest, bool force); int (*irq_retrigger)(struct irq_data *data); int (*irq_set_type)(struct irq_data *data, unsigned int flow_type); + int (*irq_read_line)(struct irq_data *data); int (*irq_set_wake)(struct irq_data *data, unsigned int on); void (*irq_bus_lock)(struct irq_data *data); @@ -416,6 +418,7 @@ extern void irq_cpu_online(void); extern void irq_cpu_offline(void); extern int irq_set_affinity_locked(struct irq_data *data, const struct cpumask *cpumask, bool force); +extern int __irq_set_affinity_locked(struct irq_data *data, const struct cpumask *cpumask); #if defined(CONFIG_SMP) && defined(CONFIG_GENERIC_PENDING_IRQ) void irq_move_irq(struct irq_data *data); @@ -466,6 +469,8 @@ extern int irq_chip_set_affinity_parent(struct irq_data *data, extern void note_interrupt(unsigned int irq, struct irq_desc *desc, irqreturn_t action_ret); +/* Resending of interrupts :*/ +void check_irq_resend(struct irq_desc *desc, unsigned int irq); /* Enable/disable irq debugging output: */ extern int noirqdebug_setup(char *str); diff --git a/include/linux/irqchip/arm-gic.h b/include/linux/irqchip/arm-gic.h index 71d706d5f169..7df86579f31b 100644 --- a/include/linux/irqchip/arm-gic.h +++ b/include/linux/irqchip/arm-gic.h @@ -102,6 +102,13 @@ void gic_init_bases(unsigned int, int, void __iomem *, void __iomem *, void gic_cascade_irq(unsigned int gic_nr, unsigned int irq); void gic_cpu_if_down(void); +bool gic_is_irq_pending(unsigned int irq); +void gic_clear_irq_pending(unsigned int irq); +#ifdef CONFIG_ARM_GIC +void gic_set_irq_secure(unsigned int irq); +#else +static inline void gic_set_irq_secure(unsigned int irq) { } +#endif static inline void gic_init(unsigned int nr, int start, void __iomem *dist , void __iomem *cpu) { @@ -121,5 +128,8 @@ static inline void __init register_routable_domain_ops { gic_routable_irq_domain_ops = ops; } +bool gic_is_spi_pending(unsigned int irq); +void gic_clear_spi_pending(unsigned int irq); + #endif /* __ASSEMBLY */ #endif diff --git a/include/linux/irqchip/msm-gpio-irq.h b/include/linux/irqchip/msm-gpio-irq.h new file mode 100644 index 000000000000..33c2d80dd3c7 --- /dev/null +++ b/include/linux/irqchip/msm-gpio-irq.h @@ -0,0 +1,38 @@ +/* Copyright (c) 2013-2014, The Linux Foundation. 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 version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef MSM_GPIO_IRQ_H +#define MSM_GPIO_IRQ_H + +#include <linux/irq.h> + +#if (defined(CONFIG_GPIO_MSM_V1) || defined(CONFIG_GPIO_MSM_V2) \ + || defined(CONFIG_GPIO_MSM_V3) && !defined(CONFIG_USE_PINCTRL_IRQ)) +int __init msm_gpio_of_init(struct device_node *node, + struct device_node *parent); +extern struct irq_chip msm_gpio_irq_extn; +static inline int __init msm_tlmm_of_irq_init(struct device_node *node, + struct device_node *parent) +{ + return 0; +} +#else +int __init msm_tlmm_of_irq_init(struct device_node *node, + struct device_node *parent); +extern struct irq_chip mpm_tlmm_irq_extn; +static inline int __init msm_gpio_of_init(struct device_node *node, + struct device_node *parent) +{ + return 0; +} +#endif +#endif diff --git a/include/linux/irqchip/msm-mpm-irq.h b/include/linux/irqchip/msm-mpm-irq.h new file mode 100644 index 000000000000..7b8a6a476560 --- /dev/null +++ b/include/linux/irqchip/msm-mpm-irq.h @@ -0,0 +1,167 @@ +/* Copyright (c) 2010-2014, The Linux Foundation. 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 version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#ifndef __MSM_MPM_IRQ_H +#define __MSM_MPM_IRQ_H + +#include <linux/types.h> +#include <linux/list.h> + +#define MSM_MPM_NR_MPM_IRQS 64 + +#if defined(CONFIG_MSM_MPM_OF) +/** + * msm_mpm_enable_pin() - Enable/Disable a MPM pin for idle wakeups. + * + * @pin: MPM pin to set + * @enable: enable/disable the pin + * + * returns 0 on success or errorno + * + * Drivers can call the function to configure MPM pins for wakeup from idle low + * power modes. The API provides a direct access to the configuring MPM pins + * that are not connected to a IRQ/GPIO + */ +int msm_mpm_enable_pin(unsigned int pin, unsigned int enable); + +/** + * msm_mpm_set_pin_wake() - Enable/Disable a MPM pin during suspend + * + * @pin: MPM pin to set + * @enable: enable/disable the pin as wakeup + * + * returns 0 on success or errorno + * + * Drivers can call the function to configure MPM pins for wakeup from suspend + * low power modes. The API provides a direct access to the configuring MPM pins + * that are not connected to a IRQ/GPIO + */ +int msm_mpm_set_pin_wake(unsigned int pin, unsigned int on); +/** + * msm_mpm_set_pin_type() - Set the flowtype of a MPM pin. + * + * @pin: MPM pin to configure + * @flow_type: flowtype of the MPM pin. + * + * returns 0 on success or errorno + * + * Drivers can call the function to configure the flowtype of the MPM pins + * The API provides a direct access to the configuring MPM pins that are not + * connected to a IRQ/GPIO + */ +int msm_mpm_set_pin_type(unsigned int pin, unsigned int flow_type); +/** + * msm_mpm_irqs_detectable() - Check if active irqs can be monitored by MPM + * + * @from_idle: indicates if the sytem is entering low power mode as a part of + * suspend/idle task. + * + * returns true if all active interrupts can be monitored by the MPM + * + * Low power management code calls into this API to check if all active + * interrupts can be monitored by MPM and choose a level such that all active + * interrupts can wake the system up from low power mode. + */ +bool msm_mpm_irqs_detectable(bool from_idle); +/** + * msm_mpm_gpio_detectable() - Check if active gpio irqs can be monitored by + * MPM + * + * @from_idle: indicates if the sytem is entering low power mode as a part of + * suspend/idle task. + * + * returns true if all active GPIO interrupts can be monitored by the MPM + * + * Low power management code calls into this API to check if all active + * GPIO interrupts can be monitored by MPM and choose a level such that all + * active interrupts can wake the system up from low power mode. + */ +bool msm_mpm_gpio_irqs_detectable(bool from_idle); +/** + * msm_mpm_enter_sleep() -Called from PM code before entering low power mode + * + * @sclk_count: wakeup time in sclk counts for programmed RPM wakeup + * @from_idle: indicates if the sytem is entering low power mode as a part of + * suspend/idle task. + * @cpumask: the next cpu to wakeup. + * + * Low power management code calls into this API to configure the MPM to + * monitor the active irqs before going to sleep. + */ +void msm_mpm_enter_sleep(uint32_t sclk_count, bool from_idle, + const struct cpumask *cpumask); +/** + * msm_mpm_exit_sleep() -Called from PM code after resuming from low power mode + * + * @from_idle: indicates if the sytem is entering low power mode as a part of + * suspend/idle task. + * + * Low power management code calls into this API to query the MPM for the + * wakeup source and retriggering the appropriate interrupt. + */ +void msm_mpm_exit_sleep(bool from_idle); +/** + * of_mpm_init() - Device tree initialization function + * + * The initialization function is called after * GPIO/GIC device initialization + * routines are called and before any device irqs are requested. MPM driver + * keeps track of all enabled/wakeup interrupts in the system to be able to + * configure MPM when entering a system wide low power mode. The MPM is a + * alway-on low power hardware block that monitors 64 wakeup interrupts when the + * system is in a low power mode. The initialization function constructs the MPM + * mapping between the IRQs and the MPM pin based on data in the device tree. + */ +void __init of_mpm_init(void); +#else +static inline int msm_mpm_enable_irq(unsigned int irq, unsigned int enable) +{ return -ENODEV; } +static inline int msm_mpm_set_irq_wake(unsigned int irq, unsigned int on) +{ return -ENODEV; } +static inline int msm_mpm_set_irq_type(unsigned int irq, unsigned int flow_type) +{ return -ENODEV; } +static inline int msm_mpm_enable_pin(unsigned int pin, unsigned int enable) +{ return -ENODEV; } +static inline int msm_mpm_set_pin_wake(unsigned int pin, unsigned int on) +{ return -ENODEV; } +static inline int msm_mpm_set_pin_type(unsigned int pin, + unsigned int flow_type) +{ return -ENODEV; } +static inline bool msm_mpm_irqs_detectable(bool from_idle) +{ return false; } +static inline bool msm_mpm_gpio_irqs_detectable(bool from_idle) +{ return false; } +static inline void msm_mpm_enter_sleep(uint32_t sclk_count, bool from_idle, + const struct cpumask *cpumask) {} +static inline void msm_mpm_exit_sleep(bool from_idle) {} +static inline void __init of_mpm_init(void) {} +#endif +#ifdef CONFIG_MSM_MPM_OF +/** msm_mpm_suspend_prepare() - Called at prepare_late() op during suspend + * + * + * When called the MPM driver checks if the wakeup interrupts can be monitored + * by MPM hardware and program them accordingly. If wake up interrupts cannot + * be monitored then it disallows system low power modes. + */ +void msm_mpm_suspend_prepare(void); +/** msm_mpm_suspend_wake - Called during wake() op in suspend. + * + * When called MPM drivers sets the vote for system low power modes depending + * on the active interrupts. + */ +void msm_mpm_suspend_wake(void); +#else +static inline void msm_mpm_suspend_prepare(void) {} +static inline void msm_mpm_suspend_wake(void) {} +#endif +#endif /* __MSM_MPM_IRQ_H */ diff --git a/include/linux/irqchip/qpnp-int.h b/include/linux/irqchip/qpnp-int.h new file mode 100644 index 000000000000..614165ebf8b3 --- /dev/null +++ b/include/linux/irqchip/qpnp-int.h @@ -0,0 +1,131 @@ +/* Copyright (c) 2012-2013, The Linux Foundation. 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 version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef QPNPINT_H +#define QPNPINT_H + +#include <linux/spmi.h> + +struct qpnp_irq_spec { + uint8_t slave; /* 0-15 */ + uint8_t per; /* 0-255 */ + uint8_t irq; /* 0-7 */ +}; + +struct qpnp_local_int { + /* mask - Invoke PMIC Arbiter local mask handler */ + int (*mask)(struct spmi_controller *spmi_ctrl, + struct qpnp_irq_spec *spec, + uint32_t priv_d); + /* unmask - Invoke PMIC Arbiter local unmask handler */ + int (*unmask)(struct spmi_controller *spmi_ctrl, + struct qpnp_irq_spec *spec, + uint32_t priv_d); + /* register_priv_data - Return per irq priv data */ + int (*register_priv_data)(struct spmi_controller *spmi_ctrl, + struct qpnp_irq_spec *spec, + uint32_t *priv_d); +}; + +#ifdef CONFIG_MSM_QPNP_INT +/** + * qpnpint_of_init() - Device Tree irq initialization + * + * Standard Device Tree init routine to be called from + * of_irq_init(). + */ +int __init qpnpint_of_init(struct device_node *node, + struct device_node *parent); + +/** + * qpnpint_register_controller() - Register local interrupt callbacks + * + * Used by the PMIC Arbiter driver or equivalent to register + * callbacks for interrupt events. + */ +int qpnpint_register_controller(struct device_node *node, + struct spmi_controller *ctrl, + struct qpnp_local_int *li_cb); + +/** + * qpnpint_unregister_controller() - Unregister local interrupt callbacks + * + * Used by the PMIC Arbiter driver or equivalent to unregister + * callbacks for interrupt events. + */ +int qpnpint_unregister_controller(struct device_node *node); + +/** + * qpnpint_handle_irq - Main interrupt handling routine + * + * Pass a PMIC Arbiter interrupt to Linux. + */ +int qpnpint_handle_irq(struct spmi_controller *spmi_ctrl, + struct qpnp_irq_spec *spec); + +/** + * qpnpint_show_irq - Prints the Linux interrupt number + * + * Pass a PMIC Arbiter interrupt to Linux. + */ +int qpnpint_show_irq(struct spmi_controller *spmi_ctrl, + struct qpnp_irq_spec *spec); + +#ifdef CONFIG_MSM_SHOW_RESUME_IRQ +extern int msm_show_resume_irq_mask; +static inline bool qpnpint_show_resume_irq(void) +{ + return msm_show_resume_irq_mask; +} +#else +static inline bool qpnpint_show_resume_irq(void) +{ + return false; +} +#endif + +#else +static inline int __init qpnpint_of_init(struct device_node *node, + struct device_node *parent) +{ + return -ENXIO; +} + +static inline int qpnpint_register_controller(struct device_node *node, + struct spmi_controller *ctrl, + struct qpnp_local_int *li_cb) +{ + return -ENXIO; +} + +static inline int qpnpint_unregister_controller(struct device_node *node) +{ + return -ENXIO; +} + +static inline int qpnpint_handle_irq(struct spmi_controller *spmi_ctrl, + struct qpnp_irq_spec *spec) +{ + return -ENXIO; +} +int qpnpint_show_irq(struct spmi_controller *spmi_ctrl, + struct qpnp_irq_spec *spec) +{ + return -ENXIO; +} + +static inline bool qpnpint_show_resume_irq(void) +{ + return false; +} +#endif /* CONFIG_MSM_QPNP_INT */ +#endif /* QPNPINT_H */ diff --git a/include/linux/kernel.h b/include/linux/kernel.h index 5449d2f4a1ef..5166ea288f56 100644 --- a/include/linux/kernel.h +++ b/include/linux/kernel.h @@ -600,7 +600,7 @@ do { \ __trace_printk_check_format(fmt, ##args); \ \ if (__builtin_constant_p(fmt)) \ - __trace_bprintk(_THIS_IP_, trace_printk_fmt, ##args); \ + __trace_printk(_THIS_IP_, trace_printk_fmt, ##args); \ else \ __trace_printk(_THIS_IP_, fmt, ##args); \ } while (0) @@ -817,4 +817,7 @@ static inline void ftrace_dump(enum ftrace_dump_mode oops_dump_mode) { } /* Other writable? Generally considered a bad idea. */ \ BUILD_BUG_ON_ZERO((perms) & 2) + \ (perms)) +/* To identify board information in panic logs, set this */ +extern char *mach_panic_string; + #endif diff --git a/include/linux/kernel_stat.h b/include/linux/kernel_stat.h index 25a822f6f000..65643fedada4 100644 --- a/include/linux/kernel_stat.h +++ b/include/linux/kernel_stat.h @@ -8,9 +8,11 @@ #include <linux/interrupt.h> #include <linux/sched.h> #include <linux/vtime.h> -#include <asm/irq.h> +#include <linux/irq.h> #include <linux/cputime.h> +#include <asm/irq.h> + /* * 'kernel_stat.h' contains the definitions needed for doing * some kernel statistics (CPU usage, context switches ...), @@ -53,7 +55,12 @@ extern unsigned long long nr_context_switches(void); extern unsigned int kstat_irqs_cpu(unsigned int irq, int cpu); extern void kstat_incr_irq_this_cpu(unsigned int irq); - +#if 0 +#define kstat_incr_irqs_this_cpu(irqno, DESC) do { \ + __this_cpu_inc(*(DESC)->kstat_irqs); \ + __this_cpu_inc(kstat.irqs_sum); \ +} while (0) +#endif static inline void kstat_incr_softirqs_this_cpu(unsigned int irq) { __this_cpu_inc(kstat.softirqs[irq]); diff --git a/include/linux/keyreset.h b/include/linux/keyreset.h new file mode 100644 index 000000000000..a2ac49e5b684 --- /dev/null +++ b/include/linux/keyreset.h @@ -0,0 +1,28 @@ +/* + * include/linux/keyreset.h - platform data structure for resetkeys driver + * + * Copyright (C) 2008 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. + * + */ + +#ifndef _LINUX_KEYRESET_H +#define _LINUX_KEYRESET_H + +#define KEYRESET_NAME "keyreset" + +struct keyreset_platform_data { + int (*reset_fn)(void); + int *keys_up; + int keys_down[]; /* 0 terminated */ +}; + +#endif /* _LINUX_KEYRESET_H */ diff --git a/include/linux/memblock.h b/include/linux/memblock.h index e8cc45307f8f..96b7073ad452 100644 --- a/include/linux/memblock.h +++ b/include/linux/memblock.h @@ -285,6 +285,7 @@ phys_addr_t memblock_end_of_DRAM(void); void memblock_enforce_memory_limit(phys_addr_t memory_limit); int memblock_is_memory(phys_addr_t addr); int memblock_is_region_memory(phys_addr_t base, phys_addr_t size); +int memblock_overlaps_memory(phys_addr_t base, phys_addr_t size); int memblock_is_reserved(phys_addr_t addr); int memblock_is_region_reserved(phys_addr_t base, phys_addr_t size); diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h index 745def862580..1b4249af9a37 100644 --- a/include/linux/mod_devicetable.h +++ b/include/linux/mod_devicetable.h @@ -432,12 +432,22 @@ struct spi_device_id { kernel_ulong_t driver_data; /* Data private to the driver */ }; +#define SLIMBUS_NAME_SIZE 32 +#define SLIMBUS_MODULE_PREFIX "slim:" + +struct slim_device_id { + char name[SLIMBUS_NAME_SIZE]; + kernel_ulong_t driver_data /* Data private to the driver */ + __attribute__((aligned(sizeof(kernel_ulong_t)))); +}; + #define SPMI_NAME_SIZE 32 #define SPMI_MODULE_PREFIX "spmi:" struct spmi_device_id { char name[SPMI_NAME_SIZE]; - kernel_ulong_t driver_data; /* Data private to the driver */ + kernel_ulong_t driver_data /* Data private to the driver */ + __attribute__((aligned(sizeof(kernel_ulong_t)))); }; /* dmi */ diff --git a/include/linux/msm-bus-board.h b/include/linux/msm-bus-board.h new file mode 100644 index 000000000000..87f17915022f --- /dev/null +++ b/include/linux/msm-bus-board.h @@ -0,0 +1,196 @@ +/* Copyright (c) 2010-2014, The Linux Foundation. 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 version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef __ASM_ARCH_MSM_BUS_BOARD_H +#define __ASM_ARCH_MSM_BUS_BOARD_H + +#include <linux/types.h> +#include <linux/input.h> + +enum context { + DUAL_CTX, + ACTIVE_CTX, + NUM_CTX +}; + +struct msm_bus_fabric_registration { + unsigned int id; + const char *name; + struct msm_bus_node_info *info; + unsigned int len; + int ahb; + const char *fabclk[NUM_CTX]; + const char *iface_clk; + unsigned int offset; + unsigned int haltid; + unsigned int rpm_enabled; + unsigned int nmasters; + unsigned int nslaves; + unsigned int ntieredslaves; + bool il_flag; + const struct msm_bus_board_algorithm *board_algo; + int hw_sel; + void *hw_data; + uint32_t qos_freq; + uint32_t qos_baseoffset; + u64 nr_lim_thresh; + uint32_t eff_fact; + uint32_t qos_delta; + bool virt; +}; + +struct msm_bus_device_node_registration { + struct msm_bus_node_device_type *info; + unsigned int num_devices; + bool virt; +}; + +enum msm_bus_bw_tier_type { + MSM_BUS_BW_TIER1 = 1, + MSM_BUS_BW_TIER2, + MSM_BUS_BW_COUNT, + MSM_BUS_BW_SIZE = 0x7FFFFFFF, +}; + +struct msm_bus_halt_vector { + uint32_t haltval; + uint32_t haltmask; +}; + +extern struct msm_bus_fabric_registration msm_bus_apps_fabric_pdata; +extern struct msm_bus_fabric_registration msm_bus_sys_fabric_pdata; +extern struct msm_bus_fabric_registration msm_bus_mm_fabric_pdata; +extern struct msm_bus_fabric_registration msm_bus_sys_fpb_pdata; +extern struct msm_bus_fabric_registration msm_bus_cpss_fpb_pdata; +extern struct msm_bus_fabric_registration msm_bus_def_fab_pdata; + +extern struct msm_bus_fabric_registration msm_bus_8960_apps_fabric_pdata; +extern struct msm_bus_fabric_registration msm_bus_8960_sys_fabric_pdata; +extern struct msm_bus_fabric_registration msm_bus_8960_mm_fabric_pdata; +extern struct msm_bus_fabric_registration msm_bus_8960_sg_mm_fabric_pdata; +extern struct msm_bus_fabric_registration msm_bus_8960_sys_fpb_pdata; +extern struct msm_bus_fabric_registration msm_bus_8960_cpss_fpb_pdata; + +extern struct msm_bus_fabric_registration msm_bus_8064_apps_fabric_pdata; +extern struct msm_bus_fabric_registration msm_bus_8064_sys_fabric_pdata; +extern struct msm_bus_fabric_registration msm_bus_8064_mm_fabric_pdata; +extern struct msm_bus_fabric_registration msm_bus_8064_sys_fpb_pdata; +extern struct msm_bus_fabric_registration msm_bus_8064_cpss_fpb_pdata; + +extern struct msm_bus_fabric_registration msm_bus_9615_sys_fabric_pdata; +extern struct msm_bus_fabric_registration msm_bus_9615_def_fab_pdata; + +extern struct msm_bus_fabric_registration msm_bus_8930_apps_fabric_pdata; +extern struct msm_bus_fabric_registration msm_bus_8930_sys_fabric_pdata; +extern struct msm_bus_fabric_registration msm_bus_8930_mm_fabric_pdata; +extern struct msm_bus_fabric_registration msm_bus_8930_sys_fpb_pdata; +extern struct msm_bus_fabric_registration msm_bus_8930_cpss_fpb_pdata; + +extern struct msm_bus_fabric_registration msm_bus_8974_sys_noc_pdata; +extern struct msm_bus_fabric_registration msm_bus_8974_mmss_noc_pdata; +extern struct msm_bus_fabric_registration msm_bus_8974_bimc_pdata; +extern struct msm_bus_fabric_registration msm_bus_8974_ocmem_noc_pdata; +extern struct msm_bus_fabric_registration msm_bus_8974_periph_noc_pdata; +extern struct msm_bus_fabric_registration msm_bus_8974_config_noc_pdata; +extern struct msm_bus_fabric_registration msm_bus_8974_ocmem_vnoc_pdata; + +extern struct msm_bus_fabric_registration msm_bus_9625_sys_noc_pdata; +extern struct msm_bus_fabric_registration msm_bus_9625_bimc_pdata; +extern struct msm_bus_fabric_registration msm_bus_9625_periph_noc_pdata; +extern struct msm_bus_fabric_registration msm_bus_9625_config_noc_pdata; + +extern int msm_bus_device_match_adhoc(struct device *dev, void *id); + +void msm_bus_rpm_set_mt_mask(void); +int msm_bus_board_rpm_get_il_ids(uint16_t *id); +int msm_bus_board_get_iid(int id); + +#define NFAB_MSM8226 6 +#define NFAB_MSM8610 5 + +/* + * These macros specify the convention followed for allocating + * ids to fabrics, masters and slaves for 8x60. + * + * A node can be identified as a master/slave/fabric by using + * these ids. + */ +#define FABRIC_ID_KEY 1024 +#define SLAVE_ID_KEY ((FABRIC_ID_KEY) >> 1) +#define MAX_FAB_KEY 7168 /* OR(All fabric ids) */ +#define INT_NODE_START 10000 + +#define GET_FABID(id) ((id) & MAX_FAB_KEY) + +#define NODE_ID(id) ((id) & (FABRIC_ID_KEY - 1)) +#define IS_SLAVE(id) ((NODE_ID(id)) >= SLAVE_ID_KEY ? 1 : 0) +#define CHECK_ID(iid, id) (((iid & id) != id) ? -ENXIO : iid) + +/* + * The following macros are used to format the data for port halt + * and unhalt requests. + */ +#define MSM_BUS_CLK_HALT 0x1 +#define MSM_BUS_CLK_HALT_MASK 0x1 +#define MSM_BUS_CLK_HALT_FIELDSIZE 0x1 +#define MSM_BUS_CLK_UNHALT 0x0 + +#define MSM_BUS_MASTER_SHIFT(master, fieldsize) \ + ((master) * (fieldsize)) + +#define MSM_BUS_SET_BITFIELD(word, fieldmask, fieldvalue) \ + { \ + (word) &= ~(fieldmask); \ + (word) |= (fieldvalue); \ + } + + +#define MSM_BUS_MASTER_HALT(u32haltmask, u32haltval, master) \ + MSM_BUS_SET_BITFIELD(u32haltmask, \ + MSM_BUS_CLK_HALT_MASK<<MSM_BUS_MASTER_SHIFT((master),\ + MSM_BUS_CLK_HALT_FIELDSIZE), \ + MSM_BUS_CLK_HALT_MASK<<MSM_BUS_MASTER_SHIFT((master),\ + MSM_BUS_CLK_HALT_FIELDSIZE))\ + MSM_BUS_SET_BITFIELD(u32haltval, \ + MSM_BUS_CLK_HALT_MASK<<MSM_BUS_MASTER_SHIFT((master),\ + MSM_BUS_CLK_HALT_FIELDSIZE), \ + MSM_BUS_CLK_HALT<<MSM_BUS_MASTER_SHIFT((master),\ + MSM_BUS_CLK_HALT_FIELDSIZE))\ + +#define MSM_BUS_MASTER_UNHALT(u32haltmask, u32haltval, master) \ + MSM_BUS_SET_BITFIELD(u32haltmask, \ + MSM_BUS_CLK_HALT_MASK<<MSM_BUS_MASTER_SHIFT((master),\ + MSM_BUS_CLK_HALT_FIELDSIZE), \ + MSM_BUS_CLK_HALT_MASK<<MSM_BUS_MASTER_SHIFT((master),\ + MSM_BUS_CLK_HALT_FIELDSIZE))\ + MSM_BUS_SET_BITFIELD(u32haltval, \ + MSM_BUS_CLK_HALT_MASK<<MSM_BUS_MASTER_SHIFT((master),\ + MSM_BUS_CLK_HALT_FIELDSIZE), \ + MSM_BUS_CLK_UNHALT<<MSM_BUS_MASTER_SHIFT((master),\ + MSM_BUS_CLK_HALT_FIELDSIZE))\ + +#define RPM_BUS_SLAVE_REQ 0x766c7362 +#define RPM_BUS_MASTER_REQ 0x73616d62 + +enum msm_bus_rpm_slave_field_type { + RPM_SLAVE_FIELD_BW = 0x00007762, +}; + +enum msm_bus_rpm_mas_field_type { + RPM_MASTER_FIELD_BW = 0x00007762, + RPM_MASTER_FIELD_BW_T0 = 0x30747762, + RPM_MASTER_FIELD_BW_T1 = 0x31747762, + RPM_MASTER_FIELD_BW_T2 = 0x32747762, +}; + +#include <dt-bindings/msm/msm-bus-ids.h> +#endif /*__ASM_ARCH_MSM_BUS_BOARD_H */ diff --git a/include/linux/msm-bus.h b/include/linux/msm-bus.h new file mode 100644 index 000000000000..1f5edc964c49 --- /dev/null +++ b/include/linux/msm-bus.h @@ -0,0 +1,139 @@ +/* Copyright (c) 2010-2014, The Linux Foundation. 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 version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _ARCH_ARM_MACH_MSM_BUS_H +#define _ARCH_ARM_MACH_MSM_BUS_H + +#include <linux/types.h> +#include <linux/input.h> +#include <linux/platform_device.h> + +/* + * Macros for clients to convert their data to ib and ab + * Ws : Time window over which to transfer the data in SECONDS + * Bs : Size of the data block in bytes + * Per : Recurrence period + * Tb : Throughput bandwidth to prevent stalling + * R : Ratio of actual bandwidth used to Tb + * Ib : Instantaneous bandwidth + * Ab : Arbitrated bandwidth + * + * IB_RECURRBLOCK and AB_RECURRBLOCK: + * These are used if the requirement is to transfer a + * recurring block of data over a known time window. + * + * IB_THROUGHPUTBW and AB_THROUGHPUTBW: + * These are used for CPU style masters. Here the requirement + * is to have minimum throughput bandwidth available to avoid + * stalling. + */ +#define IB_RECURRBLOCK(Ws, Bs) ((Ws) == 0 ? 0 : ((Bs)/(Ws))) +#define AB_RECURRBLOCK(Ws, Per) ((Ws) == 0 ? 0 : ((Bs)/(Per))) +#define IB_THROUGHPUTBW(Tb) (Tb) +#define AB_THROUGHPUTBW(Tb, R) ((Tb) * (R)) + +struct msm_bus_vectors { + int src; /* Master */ + int dst; /* Slave */ + uint64_t ab; /* Arbitrated bandwidth */ + uint64_t ib; /* Instantaneous bandwidth */ +}; + +struct msm_bus_paths { + int num_paths; + struct msm_bus_vectors *vectors; +}; + +struct msm_bus_scale_pdata { + struct msm_bus_paths *usecase; + int num_usecases; + const char *name; + /* + * If the active_only flag is set to 1, the BW request is applied + * only when at least one CPU is active (powered on). If the flag + * is set to 0, then the BW request is always applied irrespective + * of the CPU state. + */ + unsigned int active_only; +}; + +/* Scaling APIs */ + +/* + * This function returns a handle to the client. This should be used to + * call msm_bus_scale_client_update_request. + * The function returns 0 if bus driver is unable to register a client + */ + +#if (defined(CONFIG_MSM_BUS_SCALING) || defined(CONFIG_BUS_TOPOLOGY_ADHOC)) +int __init msm_bus_fabric_init_driver(void); +uint32_t msm_bus_scale_register_client(struct msm_bus_scale_pdata *pdata); +int msm_bus_scale_client_update_request(uint32_t cl, unsigned int index); +void msm_bus_scale_unregister_client(uint32_t cl); +/* AXI Port configuration APIs */ +int msm_bus_axi_porthalt(int master_port); +int msm_bus_axi_portunhalt(int master_port); + +#else +static inline int __init msm_bus_fabric_init_driver(void) { return 0; } + +static inline uint32_t +msm_bus_scale_register_client(struct msm_bus_scale_pdata *pdata) +{ + return 1; +} + +static inline int +msm_bus_scale_client_update_request(uint32_t cl, unsigned int index) +{ + return 0; +} + +static inline void +msm_bus_scale_unregister_client(uint32_t cl) +{ +} + +static inline int msm_bus_axi_porthalt(int master_port) +{ + return 0; +} + +static inline int msm_bus_axi_portunhalt(int master_port) +{ + return 0; +} +#endif + +#if defined(CONFIG_OF) && defined(CONFIG_MSM_BUS_SCALING) +struct msm_bus_scale_pdata *msm_bus_pdata_from_node( + struct platform_device *pdev, struct device_node *of_node); +struct msm_bus_scale_pdata *msm_bus_cl_get_pdata(struct platform_device *pdev); +void msm_bus_cl_clear_pdata(struct msm_bus_scale_pdata *pdata); +#else +static inline struct msm_bus_scale_pdata +*msm_bus_cl_get_pdata(struct platform_device *pdev) +{ + return NULL; +} + +static inline struct msm_bus_scale_pdata *msm_bus_pdata_from_node( + struct platform_device *pdev, struct device_node *of_node) +{ + return NULL; +} + +static inline void msm_bus_cl_clear_pdata(struct msm_bus_scale_pdata *pdata) +{ +} +#endif +#endif /*_ARCH_ARM_MACH_MSM_BUS_H*/ diff --git a/include/linux/msm_audio_ion.h b/include/linux/msm_audio_ion.h new file mode 100644 index 000000000000..38b27bf8a053 --- /dev/null +++ b/include/linux/msm_audio_ion.h @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2013, The Linux Foundation. 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 version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _LINUX_MSM_AUDIO_ION_H +#define _LINUX_MSM_AUDIO_ION_H +#ifdef CONFIG_SND_SOC_QDSP6V2 +#include <sound/q6asm-v2.h> +#else +#include <sound/q6asm.h> +#endif +#include <sound/pcm.h> +#include <linux/msm_ion.h> + + +int msm_audio_ion_alloc(const char *name, struct ion_client **client, + struct ion_handle **handle, size_t bufsz, + ion_phys_addr_t *paddr, size_t *pa_len, void **vaddr); + +int msm_audio_ion_import(const char *name, struct ion_client **client, + struct ion_handle **handle, int fd, + unsigned long *ionflag, size_t bufsz, + ion_phys_addr_t *paddr, size_t *pa_len, void **vaddr); +int msm_audio_ion_free(struct ion_client *client, struct ion_handle *handle); +int msm_audio_ion_mmap(struct audio_buffer *substream, + struct vm_area_struct *vma); + +bool msm_audio_ion_is_smmu_available(void); +int msm_audio_ion_cache_operations(struct audio_buffer *abuff, int cache_op); + +#ifdef CONFIG_SND_SOC_QDSP6V2 +struct ion_client *msm_audio_ion_client_create(unsigned int heap_mask, + const char *name); +void msm_audio_ion_client_destroy(struct ion_client *client); +int msm_audio_ion_import_legacy(const char *name, struct ion_client *client, + struct ion_handle **handle, int fd, + unsigned long *ionflag, size_t bufsz, + ion_phys_addr_t *paddr, size_t *pa_len, void **vaddr); +int msm_audio_ion_free_legacy(struct ion_client *client, + struct ion_handle *handle); +#else +static struct ion_client *msm_audio_ion_client_create(unsigned int heap_mask, + const char *name) +{ return NULL; } +static void msm_audio_ion_client_destroy(struct ion_client *client) +{} +static int msm_audio_ion_import_legacy(const char *name, + struct ion_client *client, + struct ion_handle **handle, int fd, + unsigned long *ionflag, size_t bufsz, + ion_phys_addr_t *paddr, size_t *pa_len, void **vaddr) +{ return 0; } +static int msm_audio_ion_free_legacy(struct ion_client *client, + struct ion_handle *handle) +{ return 0; } + +#endif /* CONFIG_MSM_QDSP6V2_CODECS */ +#endif /* _LINUX_MSM_AUDIO_ION_H */ + diff --git a/include/linux/msm_kgsl.h b/include/linux/msm_kgsl.h new file mode 100644 index 000000000000..75b7f39e5538 --- /dev/null +++ b/include/linux/msm_kgsl.h @@ -0,0 +1,113 @@ +#ifndef _MSM_KGSL_H +#define _MSM_KGSL_H + +#include <uapi/linux/msm_kgsl.h> + +/* Clock flags to show which clocks should be controled by a given platform */ +#define KGSL_CLK_SRC 0x00000001 +#define KGSL_CLK_CORE 0x00000002 +#define KGSL_CLK_IFACE 0x00000004 +#define KGSL_CLK_MEM 0x00000008 +#define KGSL_CLK_MEM_IFACE 0x00000010 +#define KGSL_CLK_AXI 0x00000020 +#define KGSL_CLK_ALT_MEM_IFACE 0x00000040 +#define KGSL_CLK_RBBMTIMER 0x00000080 + +#define KGSL_MAX_PWRLEVELS 10 + +#define KGSL_3D0_REG_MEMORY "kgsl_3d0_reg_memory" +#define KGSL_3D0_SHADER_MEMORY "kgsl_3d0_shader_memory" +#define KGSL_3D0_IRQ "kgsl_3d0_irq" + +enum kgsl_iommu_context_id { + KGSL_IOMMU_CONTEXT_USER = 0, + KGSL_IOMMU_CONTEXT_PRIV = 1, +}; + +/** + * struct kgsl_iommu_ctx - Struct holding context name and id + * @iommu_ctx_name: Context name + * @ctx_id: Iommu context ID - user or priv + */ +struct kgsl_iommu_ctx { + const char *iommu_ctx_name; + enum kgsl_iommu_context_id ctx_id; +}; + +/** + * struct kgsl_device_iommu_data - Struct holding iommu context data obtained + * from dtsi file + * @iommu_ctxs: Pointer to array of struct holding context name and id + * @iommu_ctx_count: Number of contexts defined in the dtsi file + * @iommu_halt_enable: Indicates if smmu halt h/w feature is supported + * @physstart: Start of iommu registers physical address + * @physend: End of iommu registers physical address + */ +struct kgsl_device_iommu_data { + const struct kgsl_iommu_ctx *iommu_ctxs; + int iommu_ctx_count; + int iommu_halt_enable; + unsigned int physstart; + unsigned int physend; +}; + +/** + * struct kgsl_pwrlevel - Struct holding different pwrlevel info obtained from + * from dtsi file + * @gpu_freq: GPU frequency vote in Hz + * @bus_freq: Bus bandwidth vote index + * @bus_min: Min bus index @gpu_freq + * @bus_max: Max bus index @gpu_freq + * @io_fraction: IO percetage vote to the CPU + */ +struct kgsl_pwrlevel { + unsigned int gpu_freq; + unsigned int bus_freq; + unsigned int bus_min; + unsigned int bus_max; + unsigned int io_fraction; +}; + +/** + * struct kgsl_device_platform_data - Struct holding all the device info + * obtained from the dtsi file + * @pwrlevel: Array of struct holding pwrlevel information + * @init_level: Pwrlevel device is initialized with + * @num_levels: Number of pwrlevels for the specific device + * @idle_timeout: Timeout for GPU to turn its resources off + * @strtstp_sleepwake: Flag to decide b/w SLEEP and SLUMBER + * @bus_control: Flag if independent bus voting is supported + * @clk_map: Clocks map per platform + * @bus_scale_table: Bus table with different b/w votes + * @iommu_data: Struct holding iommu context data + * @iommu_count: Number of IOMMU units for the GPU + * @csdev: Pointer to the coresight device for this device + * @coresight_pdata: Coresight configuration for specific device + * @chipid: Chip ID for the device's GPU + * @pm_qos_latency: latency value for cpu + */ +struct kgsl_device_platform_data { + struct kgsl_pwrlevel pwrlevel[KGSL_MAX_PWRLEVELS]; + int init_level; + int num_levels; + unsigned int idle_timeout; + bool strtstp_sleepwake; + bool bus_control; + unsigned int clk_map; + unsigned int step_mul; + struct msm_bus_scale_pdata *bus_scale_table; + struct kgsl_device_iommu_data *iommu_data; + int iommu_count; + struct coresight_device *csdev; + struct coresight_platform_data *coresight_pdata; + unsigned int chipid; + unsigned int pm_qos_latency; +}; + +#ifdef CONFIG_MSM_KGSL_DRM +int kgsl_gem_obj_addr(int drm_fd, int handle, unsigned long *start, + unsigned long *len); +#else +#define kgsl_gem_obj_addr(...) 0 +#endif +#endif /* _MSM_KGSL_H */ diff --git a/include/linux/msm_mdp.h b/include/linux/msm_mdp.h index fe722c1fb61d..1eb2e93e65a2 100644 --- a/include/linux/msm_mdp.h +++ b/include/linux/msm_mdp.h @@ -1,6 +1,7 @@ /* include/linux/msm_mdp.h * * Copyright (C) 2007 Google Incorporated + * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved. * * This software is licensed under the terms of the GNU General Public * License version 2, as published by the Free Software Foundation, and @@ -14,66 +15,22 @@ #ifndef _MSM_MDP_H_ #define _MSM_MDP_H_ -#include <linux/types.h> - -#define MSMFB_IOCTL_MAGIC 'm' -#define MSMFB_GRP_DISP _IOW(MSMFB_IOCTL_MAGIC, 1, unsigned int) -#define MSMFB_BLIT _IOW(MSMFB_IOCTL_MAGIC, 2, unsigned int) - -enum { - MDP_RGB_565, /* RGB 565 planar */ - MDP_XRGB_8888, /* RGB 888 padded */ - MDP_Y_CBCR_H2V2, /* Y and CbCr, pseudo planar w/ Cb is in MSB */ - MDP_ARGB_8888, /* ARGB 888 */ - MDP_RGB_888, /* RGB 888 planar */ - MDP_Y_CRCB_H2V2, /* Y and CrCb, pseudo planar w/ Cr is in MSB */ - MDP_YCRYCB_H2V1, /* YCrYCb interleave */ - MDP_Y_CRCB_H2V1, /* Y and CrCb, pseduo planar w/ Cr is in MSB */ - MDP_Y_CBCR_H2V1, /* Y and CrCb, pseduo planar w/ Cr is in MSB */ - MDP_RGBA_8888, /* ARGB 888 */ - MDP_BGRA_8888, /* ABGR 888 */ - MDP_RGBX_8888, /* RGBX 888 */ - MDP_IMGTYPE_LIMIT /* Non valid image type after this enum */ -}; - -enum { - PMEM_IMG, - FB_IMG, -}; - -/* flag values */ -#define MDP_ROT_NOP 0 -#define MDP_FLIP_LR 0x1 -#define MDP_FLIP_UD 0x2 -#define MDP_ROT_90 0x4 -#define MDP_ROT_180 (MDP_FLIP_UD|MDP_FLIP_LR) -#define MDP_ROT_270 (MDP_ROT_90|MDP_FLIP_UD|MDP_FLIP_LR) -#define MDP_DITHER 0x8 -#define MDP_BLUR 0x10 - -#define MDP_TRANSP_NOP 0xffffffff -#define MDP_ALPHA_NOP 0xff - -struct mdp_rect { - u32 x, y, w, h; -}; - -struct mdp_img { - u32 width, height, format, offset; - int memory_id; /* the file descriptor */ -}; - -struct mdp_blit_req { - struct mdp_img src; - struct mdp_img dst; - struct mdp_rect src_rect; - struct mdp_rect dst_rect; - u32 alpha, transp_mask, flags; -}; - -struct mdp_blit_req_list { - u32 count; - struct mdp_blit_req req[]; -}; - -#endif /* _MSM_MDP_H_ */ +#include <uapi/linux/msm_mdp.h> + +int msm_fb_get_iommu_domain(struct fb_info *info, int domain); +/* get the framebuffer physical address information */ +int get_fb_phys_info(unsigned long *start, unsigned long *len, int fb_num, + int subsys_id); +struct fb_info *msm_fb_get_writeback_fb(void); +int msm_fb_writeback_init(struct fb_info *info); +int msm_fb_writeback_start(struct fb_info *info); +int msm_fb_writeback_queue_buffer(struct fb_info *info, + struct msmfb_data *data); +int msm_fb_writeback_dequeue_buffer(struct fb_info *info, + struct msmfb_data *data); +int msm_fb_writeback_stop(struct fb_info *info); +int msm_fb_writeback_terminate(struct fb_info *info); +int msm_fb_writeback_set_secure(struct fb_info *info, int enable); +int msm_fb_writeback_iommu_ref(struct fb_info *info, int enable); + +#endif /*_MSM_MDP_H_*/ diff --git a/include/linux/msm_remote_spinlock.h b/include/linux/msm_remote_spinlock.h new file mode 100644 index 000000000000..f777cef4e1d7 --- /dev/null +++ b/include/linux/msm_remote_spinlock.h @@ -0,0 +1,74 @@ +/* Copyright (c) 2009, 2011, 2013-2014 The Linux Foundation. + * 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 version 2 and + * only 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. + * + */ + +/* + * Part of this this code is based on the standard ARM spinlock + * implementation (asm/spinlock.h) found in the 2.6.29 kernel. + */ + +#ifndef __ASM__ARCH_QC_REMOTE_SPINLOCK_H +#define __ASM__ARCH_QC_REMOTE_SPINLOCK_H + +#include <linux/io.h> +#include <linux/types.h> + +#define REMOTE_SPINLOCK_NUM_PID 128 +#define REMOTE_SPINLOCK_TID_START REMOTE_SPINLOCK_NUM_PID + +/* Remote spinlock definitions. */ + +typedef struct { + volatile uint32_t lock; +} raw_remote_spinlock_t; + +typedef raw_remote_spinlock_t *_remote_spinlock_t; + +#define remote_spinlock_id_t const char * + +#if defined(CONFIG_REMOTE_SPINLOCK_MSM) +int _remote_spin_lock_init(remote_spinlock_id_t, _remote_spinlock_t *lock); +void _remote_spin_release_all(uint32_t pid); +void _remote_spin_lock(_remote_spinlock_t *lock); +void _remote_spin_unlock(_remote_spinlock_t *lock); +int _remote_spin_trylock(_remote_spinlock_t *lock); +int _remote_spin_release(_remote_spinlock_t *lock, uint32_t pid); +int _remote_spin_owner(_remote_spinlock_t *lock); +void _remote_spin_lock_rlock_id(_remote_spinlock_t *lock, uint32_t tid); +void _remote_spin_unlock_rlock(_remote_spinlock_t *lock); +#else +static inline +int _remote_spin_lock_init(remote_spinlock_id_t id, _remote_spinlock_t *lock) +{ + return -EINVAL; +} +static inline void _remote_spin_release_all(uint32_t pid) {} +static inline void _remote_spin_lock(_remote_spinlock_t *lock) {} +static inline void _remote_spin_unlock(_remote_spinlock_t *lock) {} +static inline int _remote_spin_trylock(_remote_spinlock_t *lock) +{ + return -ENODEV; +} +static inline int _remote_spin_release(_remote_spinlock_t *lock, uint32_t pid) +{ + return -ENODEV; +} +static inline int _remote_spin_owner(_remote_spinlock_t *lock) +{ + return -ENODEV; +} +static inline void _remote_spin_lock_rlock_id(_remote_spinlock_t *lock, + uint32_t tid) {} +static inline void _remote_spin_unlock_rlock(_remote_spinlock_t *lock) {} +#endif +#endif /* __ASM__ARCH_QC_REMOTE_SPINLOCK_H */ diff --git a/include/linux/msm_rtb.h b/include/linux/msm_rtb.h new file mode 100644 index 000000000000..f8033c02feb2 --- /dev/null +++ b/include/linux/msm_rtb.h @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2012-2014, The Linux Foundation. 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 version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#ifndef __MSM_RTB_H__ +#define __MSM_RTB_H__ + +/* + * These numbers are used from the kernel command line and sysfs + * to control filtering. Remove items from here with extreme caution. + */ +enum logk_event_type { + LOGK_NONE = 0, + LOGK_READL = 1, + LOGK_WRITEL = 2, + LOGK_LOGBUF = 3, + LOGK_HOTPLUG = 4, + LOGK_CTXID = 5, + LOGK_TIMESTAMP = 6, + LOGK_L2CPREAD = 7, + LOGK_L2CPWRITE = 8, +}; + +#define LOGTYPE_NOPC 0x80 + +struct msm_rtb_platform_data { + unsigned int size; +}; + +#if defined(CONFIG_MSM_RTB) +/* + * returns 1 if data was logged, 0 otherwise + */ +int uncached_logk_pc(enum logk_event_type log_type, void *caller, + void *data); + +/* + * returns 1 if data was logged, 0 otherwise + */ +int uncached_logk(enum logk_event_type log_type, void *data); + +#define ETB_WAYPOINT do { \ + BRANCH_TO_NEXT_ISTR; \ + nop(); \ + BRANCH_TO_NEXT_ISTR; \ + nop(); \ + } while (0) + +#define BRANCH_TO_NEXT_ISTR asm volatile("b .+4\n" : : : "memory") +/* + * both the mb and the isb are needed to ensure enough waypoints for + * etb tracing + */ +#define LOG_BARRIER do { \ + mb(); \ + isb();\ + } while (0) +#else + +static inline int uncached_logk_pc(enum logk_event_type log_type, + void *caller, + void *data) { return 0; } + +static inline int uncached_logk(enum logk_event_type log_type, + void *data) { return 0; } + +#define ETB_WAYPOINT +#define BRANCH_TO_NEXT_ISTR +/* + * Due to a GCC bug, we need to have a nop here in order to prevent an extra + * read from being generated after the write. + */ +#define LOG_BARRIER nop() +#endif +#endif diff --git a/include/linux/msm_smd_pkt.h b/include/linux/msm_smd_pkt.h new file mode 100644 index 000000000000..cba9f6f27137 --- /dev/null +++ b/include/linux/msm_smd_pkt.h @@ -0,0 +1,23 @@ +/* Copyright (c) 2010, The Linux Foundation. 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 version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ +#ifndef __LINUX_MSM_SMD_PKT_H +#define __LINUX_MSM_SMD_PKT_H + +#include <linux/ioctl.h> + +#define SMD_PKT_IOCTL_MAGIC (0xC2) + +#define SMD_PKT_IOCTL_BLOCKING_WRITE \ + _IOR(SMD_PKT_IOCTL_MAGIC, 0, unsigned int) + +#endif /* __LINUX_MSM_SMD_PKT_H */ diff --git a/include/linux/percpu-defs.h b/include/linux/percpu-defs.h index 57f3a1c550dc..641d83b92b59 100644 --- a/include/linux/percpu-defs.h +++ b/include/linux/percpu-defs.h @@ -53,6 +53,19 @@ __attribute__((section(".discard"), unused)) /* + * Macro which verifies @ptr is a percpu pointer without evaluating + * @ptr. This is to be used in percpu accessors to verify that the + * input parameter is a percpu pointer. + * + * + 0 is required in order to convert the pointer type from a + * potential array type to a pointer to a single item of the array. + */ +#define __verify_pcpu_ptr(ptr) do { \ + const void __percpu *__vpp_verify = (typeof((ptr) + 0))NULL; \ + (void)__vpp_verify; \ +} while (0) + +/* * s390 and alpha modules require percpu variables to be defined as * weak to force the compiler to generate GOT based external * references for them. This is necessary because percpu sections diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h index 486e84ccb1f9..d3eae1c0f929 100644 --- a/include/linux/perf_event.h +++ b/include/linux/perf_event.h @@ -193,6 +193,8 @@ struct pmu { struct perf_cpu_context * __percpu pmu_cpu_context; int task_ctx_nr; int hrtimer_interval_ms; + u32 events_across_hotplug:1, + reserved:31; /* * Fully disable/enable this PMU, can be used to protect from the PMI diff --git a/include/linux/pm_opp.h b/include/linux/pm_opp.h index cec2d4540914..c3769b407975 100644 --- a/include/linux/pm_opp.h +++ b/include/linux/pm_opp.h @@ -16,7 +16,8 @@ #include <linux/err.h> #include <linux/notifier.h> - +#include <linux/cpufreq.h> +# struct dev_pm_opp; struct device; diff --git a/include/linux/power_supply.h b/include/linux/power_supply.h index 096dbced02ac..9a20b6f061b0 100644 --- a/include/linux/power_supply.h +++ b/include/linux/power_supply.h @@ -44,16 +44,19 @@ enum { POWER_SUPPLY_CHARGE_TYPE_NONE, POWER_SUPPLY_CHARGE_TYPE_TRICKLE, POWER_SUPPLY_CHARGE_TYPE_FAST, + POWER_SUPPLY_CHARGE_TYPE_TAPER, }; enum { POWER_SUPPLY_HEALTH_UNKNOWN = 0, POWER_SUPPLY_HEALTH_GOOD, POWER_SUPPLY_HEALTH_OVERHEAT, + POWER_SUPPLY_HEALTH_WARM, POWER_SUPPLY_HEALTH_DEAD, POWER_SUPPLY_HEALTH_OVERVOLTAGE, POWER_SUPPLY_HEALTH_UNSPEC_FAILURE, POWER_SUPPLY_HEALTH_COLD, + POWER_SUPPLY_HEALTH_COOL, POWER_SUPPLY_HEALTH_WATCHDOG_TIMER_EXPIRE, POWER_SUPPLY_HEALTH_SAFETY_TIMER_EXPIRE, }; @@ -91,6 +94,7 @@ enum power_supply_property { POWER_SUPPLY_PROP_PRESENT, POWER_SUPPLY_PROP_ONLINE, POWER_SUPPLY_PROP_AUTHENTIC, + POWER_SUPPLY_PROP_CHARGING_ENABLED, POWER_SUPPLY_PROP_TECHNOLOGY, POWER_SUPPLY_PROP_CYCLE_COUNT, POWER_SUPPLY_PROP_VOLTAGE_MAX, @@ -101,7 +105,11 @@ enum power_supply_property { POWER_SUPPLY_PROP_VOLTAGE_AVG, POWER_SUPPLY_PROP_VOLTAGE_OCV, POWER_SUPPLY_PROP_VOLTAGE_BOOT, + POWER_SUPPLY_PROP_INPUT_VOLTAGE_REGULATION, POWER_SUPPLY_PROP_CURRENT_MAX, + POWER_SUPPLY_PROP_INPUT_CURRENT_MAX, + POWER_SUPPLY_PROP_INPUT_CURRENT_TRIM, + POWER_SUPPLY_PROP_INPUT_CURRENT_SETTLED, POWER_SUPPLY_PROP_CURRENT_NOW, POWER_SUPPLY_PROP_CURRENT_AVG, POWER_SUPPLY_PROP_CURRENT_BOOT, @@ -114,6 +122,7 @@ enum power_supply_property { POWER_SUPPLY_PROP_CHARGE_NOW, POWER_SUPPLY_PROP_CHARGE_AVG, POWER_SUPPLY_PROP_CHARGE_COUNTER, + POWER_SUPPLY_PROP_CHARGE_COUNTER_SHADOW, POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT, POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX, POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE, @@ -127,6 +136,8 @@ enum power_supply_property { POWER_SUPPLY_PROP_ENERGY_EMPTY, POWER_SUPPLY_PROP_ENERGY_NOW, POWER_SUPPLY_PROP_ENERGY_AVG, + POWER_SUPPLY_PROP_HI_POWER, + POWER_SUPPLY_PROP_LOW_POWER, POWER_SUPPLY_PROP_CAPACITY, /* in percents! */ POWER_SUPPLY_PROP_CAPACITY_ALERT_MIN, /* in percents! */ POWER_SUPPLY_PROP_CAPACITY_ALERT_MAX, /* in percents! */ @@ -136,6 +147,8 @@ enum power_supply_property { POWER_SUPPLY_PROP_TEMP_MIN, POWER_SUPPLY_PROP_TEMP_ALERT_MIN, POWER_SUPPLY_PROP_TEMP_ALERT_MAX, + POWER_SUPPLY_PROP_COOL_TEMP, + POWER_SUPPLY_PROP_WARM_TEMP, POWER_SUPPLY_PROP_TEMP_AMBIENT, POWER_SUPPLY_PROP_TEMP_AMBIENT_ALERT_MIN, POWER_SUPPLY_PROP_TEMP_AMBIENT_ALERT_MAX, @@ -147,10 +160,18 @@ enum power_supply_property { POWER_SUPPLY_PROP_SCOPE, POWER_SUPPLY_PROP_CHARGE_TERM_CURRENT, POWER_SUPPLY_PROP_CALIBRATE, + POWER_SUPPLY_PROP_SYSTEM_TEMP_LEVEL, + POWER_SUPPLY_PROP_RESISTANCE, + POWER_SUPPLY_PROP_RESISTANCE_CAPACITIVE, + /* Local extensions */ + POWER_SUPPLY_PROP_USB_HC, + POWER_SUPPLY_PROP_USB_OTG, + POWER_SUPPLY_PROP_CHARGE_ENABLED, /* Properties of type `const char *' */ POWER_SUPPLY_PROP_MODEL_NAME, POWER_SUPPLY_PROP_MANUFACTURER, POWER_SUPPLY_PROP_SERIAL_NUMBER, + POWER_SUPPLY_PROP_BATTERY_TYPE, }; enum power_supply_type { @@ -162,6 +183,9 @@ enum power_supply_type { POWER_SUPPLY_TYPE_USB_DCP, /* Dedicated Charging Port */ POWER_SUPPLY_TYPE_USB_CDP, /* Charging Downstream Port */ POWER_SUPPLY_TYPE_USB_ACA, /* Accessory Charger Adapters */ + POWER_SUPPLY_TYPE_WIRELESS, /* Accessory Charger Adapters */ + POWER_SUPPLY_TYPE_BMS, /* Battery Monitor System */ + POWER_SUPPLY_TYPE_USB_PARALLEL, /* USB Parallel Path */ }; enum power_supply_notifier_events { @@ -255,6 +279,7 @@ struct power_supply_info { extern struct atomic_notifier_head power_supply_notifier; extern int power_supply_reg_notifier(struct notifier_block *nb); extern void power_supply_unreg_notifier(struct notifier_block *nb); +#if defined(CONFIG_POWER_SUPPLY) extern struct power_supply *power_supply_get_by_name(const char *name); #ifdef CONFIG_OF extern struct power_supply *power_supply_get_by_phandle(struct device_node *np, @@ -267,19 +292,71 @@ power_supply_get_by_phandle(struct device_node *np, const char *property) extern void power_supply_changed(struct power_supply *psy); extern int power_supply_am_i_supplied(struct power_supply *psy); extern int power_supply_set_battery_charged(struct power_supply *psy); - -#ifdef CONFIG_POWER_SUPPLY +extern int power_supply_set_current_limit(struct power_supply *psy, int limit); +extern int power_supply_set_online(struct power_supply *psy, bool enable); +extern int power_supply_set_health_state(struct power_supply *psy, int health); +extern int power_supply_set_present(struct power_supply *psy, bool enable); +extern int power_supply_set_scope(struct power_supply *psy, int scope); +extern int power_supply_set_usb_otg(struct power_supply *psy, int otg); +extern int power_supply_set_charge_type(struct power_supply *psy, int type); +extern int power_supply_set_supply_type(struct power_supply *psy, + enum power_supply_type supply_type); +extern int power_supply_set_hi_power_state(struct power_supply *psy, int value); +extern int power_supply_set_low_power_state(struct power_supply *psy, + int value); extern int power_supply_is_system_supplied(void); -#else -static inline int power_supply_is_system_supplied(void) { return -ENOSYS; } -#endif - extern int power_supply_register(struct device *parent, struct power_supply *psy); extern int power_supply_register_no_ws(struct device *parent, struct power_supply *psy); extern void power_supply_unregister(struct power_supply *psy); extern int power_supply_powers(struct power_supply *psy, struct device *dev); +#else +static inline struct power_supply *power_supply_get_by_name(char *name) + { return NULL; } +static inline void power_supply_changed(struct power_supply *psy) { } +static inline int power_supply_am_i_supplied(struct power_supply *psy) + { return -ENOSYS; } +static inline int power_supply_set_battery_charged(struct power_supply *psy) + { return -ENOSYS; } +static inline int power_supply_set_current_limit(struct power_supply *psy, + int limit) + { return -ENOSYS; } +static inline int power_supply_set_online(struct power_supply *psy, + bool enable) + { return -ENOSYS; } +static inline int power_supply_set_health_state(struct power_supply *psy, + int health) + { return -ENOSYS; } +static inline int power_supply_set_present(struct power_supply *psy, + bool enable) + { return -ENOSYS; } +static inline int power_supply_set_scope(struct power_supply *psy, + int scope) + { return -ENOSYS; } +static inline int power_supply_set_usb_otg(struct power_supply *psy, int otg) + { return -ENOSYS; } +static inline int power_supply_set_charge_type(struct power_supply *psy, + int type) + { return -ENOSYS; } +static inline int power_supply_set_supply_type(struct power_supply *psy, + enum power_supply_type supply_type) + { return -ENOSYS; } +static inline int power_supply_set_hi_power_state(struct power_supply *psy, + int value) + { return -ENOSYS; } +static inline int power_supply_set_low_power_state(struct power_supply *psy, + int value) + { return -ENOSYS; } +static inline int power_supply_is_system_supplied(void) { return -ENOSYS; } +static inline int power_supply_register(struct device *parent, + struct power_supply *psy) + { return -ENOSYS; } +static inline void power_supply_unregister(struct power_supply *psy) { } +static inline int power_supply_powers(struct power_supply *psy, + struct device *dev) + { return -ENOSYS; } +#endif /* For APM emulation, think legacy userspace. */ extern struct class *power_supply_class; @@ -294,9 +371,11 @@ static inline bool power_supply_is_amp_property(enum power_supply_property psp) case POWER_SUPPLY_PROP_CHARGE_NOW: case POWER_SUPPLY_PROP_CHARGE_AVG: case POWER_SUPPLY_PROP_CHARGE_COUNTER: + case POWER_SUPPLY_PROP_CHARGE_COUNTER_SHADOW: case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT: case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX: case POWER_SUPPLY_PROP_CURRENT_MAX: + case POWER_SUPPLY_PROP_INPUT_CURRENT_MAX: case POWER_SUPPLY_PROP_CURRENT_NOW: case POWER_SUPPLY_PROP_CURRENT_AVG: case POWER_SUPPLY_PROP_CURRENT_BOOT: diff --git a/include/linux/qcomwlan_secif.h b/include/linux/qcomwlan_secif.h new file mode 100644 index 000000000000..6334e3dc7b6b --- /dev/null +++ b/include/linux/qcomwlan_secif.h @@ -0,0 +1,41 @@ +/* Copyright (c) 2011-2013, The Linux Foundation. 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 version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef __QCOM_WLAN_SECIF_H__ +#define __QCOM_WLAN_SECIF_H__ + +#include <crypto/hash.h> + +#define CMAC_TLEN 8 /* CMAC TLen = 64 bits (8 octets) */ + +/* + * Prototypes for WLAN Security Interface Functions + */ + +extern struct crypto_ahash * +wcnss_wlan_crypto_alloc_ahash(const char *alg_name, u32 type, u32 mask); + +extern int wcnss_wlan_crypto_ahash_digest(struct ahash_request *req); +extern void wcnss_wlan_crypto_free_ahash(struct crypto_ahash *tfm); +extern int wcnss_wlan_crypto_ahash_setkey(struct crypto_ahash *tfm, + const u8 *key, unsigned int keylen); +extern struct crypto_ablkcipher * +wcnss_wlan_crypto_alloc_ablkcipher(const char *alg_name, u32 type, u32 mask); +extern void wcnss_wlan_ablkcipher_request_free(struct ablkcipher_request *req); +extern void wcnss_wlan_crypto_free_cipher(struct crypto_cipher *tfm); +extern void wcnss_wlan_crypto_free_ablkcipher(struct crypto_ablkcipher *tfm); +extern struct crypto_cipher * +wcnss_wlan_crypto_alloc_cipher(const char *alg_name, u32 type, u32 mask); +extern void wcnss_wlan_cmac_calc_mic(struct crypto_cipher *tfm, u8 *m, + u16 length, u8 *mac); + +#endif /* __QCOM_WLAN_SECIF_H__ */ diff --git a/include/linux/qfp_fuse.h b/include/linux/qfp_fuse.h new file mode 100644 index 000000000000..d2f89618adc0 --- /dev/null +++ b/include/linux/qfp_fuse.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2011, The Linux Foundation. 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 version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#ifndef _QFP_FUSE_H_ +#define _QFP_FUSE_H_ + +#include <linux/types.h> +#include <linux/ioctl.h> + +#define QFP_FUSE_IOC_MAGIC 0x92 + +#define QFP_FUSE_IOC_WRITE _IO(QFP_FUSE_IOC_MAGIC, 1) +#define QFP_FUSE_IOC_READ _IO(QFP_FUSE_IOC_MAGIC, 2) + + +/* + * This structure is used to exchange the fuse parameters with the user + * space application. The pointer to this structure is passed to the ioctl + * function. + * offset = offset from the QFPROM base for the data to be read/written. + * size = number of 32-bit words to be read/written. + * data = pointer to the 32 bit word denoting userspace data. + */ +struct qfp_fuse_req { + u32 offset; + u32 size; + u32 *data; +}; + +#endif diff --git a/include/linux/qpnp-misc.h b/include/linux/qpnp-misc.h new file mode 100644 index 000000000000..c65e629dd3cc --- /dev/null +++ b/include/linux/qpnp-misc.h @@ -0,0 +1,38 @@ +/* Copyright (c) 2013, The Linux Foundation. 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 version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef __QPNP_MISC_H +#define __QPNP_MISC_H + +#include <linux/errno.h> + +#ifdef CONFIG_QPNP_MISC +/** + * qpnp_misc_irqs_available - check if IRQs are available + * + * @consumer_dev: device struct + * + * This function returns true if the MISC interrupts are available + * based on a check in the MISC peripheral revision registers. + * + * Any consumer of this function needs to reference a MISC device phandle + * using the "qcom,misc-ref" property in their device tree node. + */ + +int qpnp_misc_irqs_available(struct device *consumer_dev); +#else +static int qpnp_misc_irqs_available(struct device *consumer_dev) +{ + return 0; +} +#endif +#endif diff --git a/include/linux/qpnp-revid.h b/include/linux/qpnp-revid.h new file mode 100644 index 000000000000..c5d6204afb88 --- /dev/null +++ b/include/linux/qpnp-revid.h @@ -0,0 +1,139 @@ +/* Copyright (c) 2013-2014, The Linux Foundation. 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 version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef __QPNP_REVID +#define __QPNP_REVID + +#define PM8226_V2P2_REV1 0x00 +#define PM8226_V2P2_REV2 0x00 +#define PM8226_V2P2_REV3 0x02 +#define PM8226_V2P2_REV4 0x02 +#define PM8226_V2P2_TYPE 0x51 +#define PM8226_V2P2_SUBTYPE 0x04 + +#define PM8226_V2P1_REV1 0x00 +#define PM8226_V2P1_REV2 0x00 +#define PM8226_V2P1_REV3 0x01 +#define PM8226_V2P1_REV4 0x02 +#define PM8226_V2P1_TYPE 0x51 +#define PM8226_V2P1_SUBTYPE 0x04 + +#define PM8226_V2P0_REV1 0x00 +#define PM8226_V2P0_REV2 0x00 +#define PM8226_V2P0_REV3 0x00 +#define PM8226_V2P0_REV4 0x02 +#define PM8226_V2P0_TYPE 0x51 +#define PM8226_V2P0_SUBTYPE 0x04 + +#define PM8226_V1P0_REV1 0x00 +#define PM8226_V1P0_REV2 0x00 +#define PM8226_V1P0_REV3 0x00 +#define PM8226_V1P0_REV4 0x00 +#define PM8226_V1P0_TYPE 0x51 +#define PM8226_V1P0_SUBTYPE 0x04 + +#define PM8941_V1P0_REV1 0x00 +#define PM8941_V1P0_REV2 0x00 +#define PM8941_V1P0_REV3 0x00 +#define PM8941_V1P0_REV4 0x01 +#define PM8941_V1P0_TYPE 0x51 +#define PM8941_V1P0_SUBTYPE 0x01 + +#define PM8941_V2P0_REV1 0x00 +#define PM8941_V2P0_REV2 0x00 +#define PM8941_V2P0_REV3 0x00 +#define PM8941_V2P0_REV4 0x01 +#define PM8941_V2P0_TYPE 0x51 +#define PM8941_V2P0_SUBTYPE 0x01 + +#define PM8941_V3P0_REV1 0x00 +#define PM8941_V3P0_REV2 0x00 +#define PM8941_V3P0_REV3 0x00 +#define PM8941_V3P0_REV4 0x03 +#define PM8941_V3P0_TYPE 0x51 +#define PM8941_V3P0_SUBTYPE 0x01 + +#define PM8941_V3P1_REV1 0x00 +#define PM8941_V3P1_REV2 0x00 +#define PM8941_V3P1_REV3 0x01 +#define PM8941_V3P1_REV4 0x03 +#define PM8941_V3P1_TYPE 0x51 +#define PM8941_V3P1_SUBTYPE 0x01 + +#define PM8110_V1P0_REV1 0x00 +#define PM8110_V1P0_REV2 0x00 +#define PM8110_V1P0_REV3 0x00 +#define PM8110_V1P0_REV4 0x01 +#define PM8110_V1P0_TYPE 0x51 +#define PM8110_V1P0_SUBTYPE 0x05 + +#define PM8110_V1P1_REV1 0x00 +#define PM8110_V1P1_REV2 0x01 +#define PM8110_V1P1_REV3 0x00 +#define PM8110_V1P1_REV4 0x01 +#define PM8110_V1P1_TYPE 0x51 +#define PM8110_V1P1_SUBTYPE 0x05 + +#define PM8110_V1P3_REV1 0x00 +#define PM8110_V1P3_REV2 0x03 +#define PM8110_V1P3_REV3 0x00 +#define PM8110_V1P3_REV4 0x01 +#define PM8110_V1P3_TYPE 0x51 +#define PM8110_V1P3_SUBTYPE 0x05 + +#define PM8110_V2P0_REV1 0x00 +#define PM8110_V2P0_REV2 0x00 +#define PM8110_V2P0_REV3 0x00 +#define PM8110_V2P0_REV4 0x02 +#define PM8110_V2P0_TYPE 0x51 +#define PM8110_V2P0_SUBTYPE 0x05 + +#define PM8916_V1P0_REV1 0x00 +#define PM8916_V1P0_REV2 0x00 +#define PM8916_V1P0_REV3 0x00 +#define PM8916_V1P0_REV4 0x01 +#define PM8916_V1P0_TYPE 0x51 +#define PM8916_V1P0_SUBTYPE 0x0B + +#define PM8916_V1P1_REV1 0x00 +#define PM8916_V1P1_REV2 0x00 +#define PM8916_V1P1_REV3 0x01 +#define PM8916_V1P1_REV4 0x01 +#define PM8916_V1P1_TYPE 0x51 +#define PM8916_V1P1_SUBTYPE 0x0B + +#define PM8916_V2P0_REV1 0x00 +#define PM8916_V2P0_REV2 0x00 +#define PM8916_V2P0_REV3 0x00 +#define PM8916_V2P0_REV4 0x02 +#define PM8916_V2P0_TYPE 0x51 +#define PM8916_V2P0_SUBTYPE 0x0B + +struct pmic_revid_data { + u8 rev1; + u8 rev2; + u8 rev3; + u8 rev4; + u8 pmic_type; + u8 pmic_subtype; +}; + +#ifdef CONFIG_QPNP_REVID +struct pmic_revid_data *get_revid_data(struct device_node *dev_node); +#else +static inline +struct pmic_revid_data *get_revid_data(struct device_node *dev_node) +{ + return NULL; +} +#endif +#endif diff --git a/include/linux/qpnp/clkdiv.h b/include/linux/qpnp/clkdiv.h new file mode 100644 index 000000000000..52537115b2ff --- /dev/null +++ b/include/linux/qpnp/clkdiv.h @@ -0,0 +1,35 @@ +/* Copyright (c) 2012, The Linux Foundation. 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 version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef QPNP_CLKDIV_H +#define QPNP_CLKDIV_H + +enum q_clkdiv_cfg { + Q_CLKDIV_NO_CLK = 0, + Q_CLKDIV_XO_DIV_1, + Q_CLKDIV_XO_DIV_2, + Q_CLKDIV_XO_DIV_4, + Q_CLKDIV_XO_DIV_8, + Q_CLKDIV_XO_DIV_16, + Q_CLKDIV_XO_DIV_32, + Q_CLKDIV_XO_DIV_64, + Q_CLKDIV_INVALID, +}; + +struct q_clkdiv; + +struct q_clkdiv *qpnp_clkdiv_get(struct device *dev, const char *name); +int qpnp_clkdiv_enable(struct q_clkdiv *q_clkdiv); +int qpnp_clkdiv_disable(struct q_clkdiv *q_clkdiv); +int qpnp_clkdiv_config(struct q_clkdiv *q_clkdiv, + enum q_clkdiv_cfg cfg); +#endif diff --git a/include/linux/qpnp/pin.h b/include/linux/qpnp/pin.h new file mode 100644 index 000000000000..4c23f091dcc0 --- /dev/null +++ b/include/linux/qpnp/pin.h @@ -0,0 +1,190 @@ +/* Copyright (c) 2012, The Linux Foundation. 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 version 2 and + * only 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. + */ + +/* Mode select */ +#define QPNP_PIN_MODE_DIG_IN 0 +#define QPNP_PIN_MODE_DIG_OUT 1 +#define QPNP_PIN_MODE_DIG_IN_OUT 2 +#define QPNP_PIN_MODE_BIDIR 3 +#define QPNP_PIN_MODE_AIN 4 +#define QPNP_PIN_MODE_AOUT 5 +#define QPNP_PIN_MODE_SINK 6 + +/* Invert source select (GPIO, MPP) */ +#define QPNP_PIN_INVERT_DISABLE 0 +#define QPNP_PIN_INVERT_ENABLE 1 + +/* Output type (GPIO) */ +#define QPNP_PIN_OUT_BUF_CMOS 0 +#define QPNP_PIN_OUT_BUF_OPEN_DRAIN_NMOS 1 +#define QPNP_PIN_OUT_BUF_OPEN_DRAIN_PMOS 2 + +/* Voltage select (GPIO, MPP) */ +#define QPNP_PIN_VIN0 0 +#define QPNP_PIN_VIN1 1 +#define QPNP_PIN_VIN2 2 +#define QPNP_PIN_VIN3 3 +#define QPNP_PIN_VIN4 4 +#define QPNP_PIN_VIN5 5 +#define QPNP_PIN_VIN6 6 +#define QPNP_PIN_VIN7 7 + +/* Pull Up Values (GPIO) */ +#define QPNP_PIN_GPIO_PULL_UP_30 0 +#define QPNP_PIN_GPIO_PULL_UP_1P5 1 +#define QPNP_PIN_GPIO_PULL_UP_31P5 2 +#define QPNP_PIN_GPIO_PULL_UP_1P5_30 3 +#define QPNP_PIN_GPIO_PULL_DN 4 +#define QPNP_PIN_GPIO_PULL_NO 5 + +/* Pull Up Values (MPP) */ +#define QPNP_PIN_MPP_PULL_UP_0P6KOHM 0 +#define QPNP_PIN_MPP_PULL_UP_OPEN 1 +#define QPNP_PIN_MPP_PULL_UP_10KOHM 2 +#define QPNP_PIN_MPP_PULL_UP_30KOHM 3 + +/* Out Strength (GPIO) */ +#define QPNP_PIN_OUT_STRENGTH_LOW 1 +#define QPNP_PIN_OUT_STRENGTH_MED 2 +#define QPNP_PIN_OUT_STRENGTH_HIGH 3 + +/* Source Select (GPIO) / Enable Select (MPP) */ +#define QPNP_PIN_SEL_FUNC_CONSTANT 0 +#define QPNP_PIN_SEL_FUNC_PAIRED 1 +#define QPNP_PIN_SEL_FUNC_1 2 +#define QPNP_PIN_SEL_FUNC_2 3 +#define QPNP_PIN_SEL_DTEST1 4 +#define QPNP_PIN_SEL_DTEST2 5 +#define QPNP_PIN_SEL_DTEST3 6 +#define QPNP_PIN_SEL_DTEST4 7 + +/* Master enable (GPIO, MPP) */ +#define QPNP_PIN_MASTER_DISABLE 0 +#define QPNP_PIN_MASTER_ENABLE 1 + +/* Analog Output (MPP) */ +#define QPNP_PIN_AOUT_1V25 0 +#define QPNP_PIN_AOUT_0V625 1 +#define QPNP_PIN_AOUT_0V3125 2 +#define QPNP_PIN_AOUT_MPP 3 +#define QPNP_PIN_AOUT_ABUS1 4 +#define QPNP_PIN_AOUT_ABUS2 5 +#define QPNP_PIN_AOUT_ABUS3 6 +#define QPNP_PIN_AOUT_ABUS4 7 + +/* Analog Input (MPP) */ +#define QPNP_PIN_AIN_AMUX_CH5 0 +#define QPNP_PIN_AIN_AMUX_CH6 1 +#define QPNP_PIN_AIN_AMUX_CH7 2 +#define QPNP_PIN_AIN_AMUX_CH8 3 +#define QPNP_PIN_AIN_AMUX_ABUS1 4 +#define QPNP_PIN_AIN_AMUX_ABUS2 5 +#define QPNP_PIN_AIN_AMUX_ABUS3 6 +#define QPNP_PIN_AIN_AMUX_ABUS4 7 + +/* Current Sink (MPP) */ +#define QPNP_PIN_CS_OUT_5MA 0 +#define QPNP_PIN_CS_OUT_10MA 1 +#define QPNP_PIN_CS_OUT_15MA 2 +#define QPNP_PIN_CS_OUT_20MA 3 +#define QPNP_PIN_CS_OUT_25MA 4 +#define QPNP_PIN_CS_OUT_30MA 5 +#define QPNP_PIN_CS_OUT_35MA 6 +#define QPNP_PIN_CS_OUT_40MA 7 + +/** + * struct qpnp_pin_cfg - structure to specify pin configurtion values + * @mode: indicates whether the pin should be input, output, or + * both for gpios. mpp pins also support bidirectional, + * analog in, analog out and current sink. This value + * should be of type QPNP_PIN_MODE_*. + * @output_type: indicates pin should be configured as CMOS or open + * drain. Should be of the type QPNP_PIN_OUT_BUF_*. This + * setting applies for gpios only. + * @invert: Invert the signal of the line - + * QPNP_PIN_INVERT_DISABLE or QPNP_PIN_INVERT_ENABLE. + * @pull: This parameter should be programmed to different values + * depending on whether it's GPIO or MPP. + * For GPIO, it indicates whether a pull up or pull down + * should be applied. If a pullup is required the + * current strength needs to be specified. + * Current values of 30uA, 1.5uA, 31.5uA, 1.5uA with 30uA + * boost are supported. This value should be one of + * the QPNP_PIN_GPIO_PULL_*. Note that the hardware ignores + * this configuration if the GPIO is not set to input or + * output open-drain mode. + * For MPP, it indicates whether a pullup should be + * applied for bidirectitional mode only. The hardware + * ignores the configuration when operating in other modes. + * This value should be one of the QPNP_PIN_MPP_PULL_*. + * @vin_sel: specifies the voltage level when the output is set to 1. + * For an input gpio specifies the voltage level at which + * the input is interpreted as a logical 1. + * @out_strength: the amount of current supplied for an output gpio, + * should be of the type QPNP_PIN_STRENGTH_*. + * @src_sel: select alternate function for the pin. Certain pins + * can be paired (shorted) with each other. Some pins + * can act as alternate functions. In the context of + * gpio, this acts as a source select. For mpps, + * this is an enable select. + * This parameter should be of type QPNP_PIN_SEL_*. + * @master_en: QPNP_PIN_MASTER_ENABLE = Enable features within the + * pin block based on configurations. + * QPNP_PIN_MASTER_DISABLE = Completely disable the pin + * block and let the pin float with high impedance + * regardless of other settings. + * @aout_ref: Set the analog output reference. This parameter should + * be of type QPNP_PIN_AOUT_*. This parameter only applies + * to mpp pins. + * @ain_route: Set the source for analog input. This parameter + * should be of type QPNP_PIN_AIN_*. This parameter only + * applies to mpp pins. + * @cs_out: Set the the amount of current to sync in mA. This + * parameter should be of type QPNP_PIN_CS_OUT_*. This + * parameter only applies to mpp pins. + */ +struct qpnp_pin_cfg { + int mode; + int output_type; + int invert; + int pull; + int vin_sel; + int out_strength; + int src_sel; + int master_en; + int aout_ref; + int ain_route; + int cs_out; +}; + +/** + * qpnp_pin_config - Apply pin configuration for Linux gpio + * @gpio: Linux gpio number to configure. + * @param: parameters to configure. + * + * This routine takes a Linux gpio number that corresponds with a + * PMIC pin and applies the configuration specified in 'param'. + * This gpio number can be ascertained by of_get_gpio_flags() or + * the qpnp_pin_map_gpio() API. + */ +int qpnp_pin_config(int gpio, struct qpnp_pin_cfg *param); + +/** + * qpnp_pin_map - Obtain Linux GPIO number from device spec + * @name: Name assigned by the 'label' binding for the primary node. + * @pmic_pin: PMIC pin number to lookup. + * + * This routine is used in legacy configurations that do not support + * Device Tree. If you are using Device Tree, you should not use this. + * For such cases, use of_get_gpio() or friends instead. + */ +int qpnp_pin_map(const char *name, uint32_t pmic_pin); diff --git a/include/linux/qpnp/power-on.h b/include/linux/qpnp/power-on.h new file mode 100644 index 000000000000..ae4e731aa90a --- /dev/null +++ b/include/linux/qpnp/power-on.h @@ -0,0 +1,73 @@ +/* Copyright (c) 2012-2013, The Linux Foundation. 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 version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef QPNP_PON_H +#define QPNP_PON_H + +#include <linux/errno.h> + +/** + * enum pon_trigger_source: List of PON trigger sources + * %PON_SMPL: PON triggered by SMPL - Sudden Momentary Power Loss + * %PON_RTC: PON triggered by RTC alarm + * %PON_DC_CHG: PON triggered by insertion of DC charger + * %PON_USB_CHG: PON triggered by insertion of USB + * %PON_PON1: PON triggered by other PMIC (multi-PMIC option) + * %PON_CBLPWR_N: PON triggered by power-cable insertion + * %PON_KPDPWR_N: PON triggered by long press of the power-key + */ +enum pon_trigger_source { + PON_SMPL = 1, + PON_RTC, + PON_DC_CHG, + PON_USB_CHG, + PON_PON1, + PON_CBLPWR_N, + PON_KPDPWR_N, +}; + +/** + * enum pon_power_off_type: Possible power off actions to perform + * %PON_POWER_OFF_WARM_RESET: Reset the MSM but not all PMIC peripherals + * %PON_POWER_OFF_SHUTDOWN: Shutdown the MSM and PMIC completely + * %PON_POWER_OFF_HARD_RESET: Reset the MSM and all PMIC peripherals +}; + */ +enum pon_power_off_type { + PON_POWER_OFF_WARM_RESET = 0x01, + PON_POWER_OFF_SHUTDOWN = 0x04, + PON_POWER_OFF_HARD_RESET = 0x07, +}; + +#ifdef CONFIG_QPNP_POWER_ON +int qpnp_pon_system_pwr_off(enum pon_power_off_type type); +int qpnp_pon_is_warm_reset(void); +int qpnp_pon_trigger_config(enum pon_trigger_source pon_src, bool enable); +int qpnp_pon_wd_config(bool enable); +#else +static int qpnp_pon_system_pwr_off(enum pon_power_off_type type) +{ + return -ENODEV; +} +static inline int qpnp_pon_is_warm_reset(void) { return -ENODEV; } +static inline int qpnp_pon_trigger_config(enum pon_trigger_source pon_src, + bool enable) +{ + return -ENODEV; +} +int qpnp_pon_wd_config(bool enable) +{ + return -ENODEV; +} +#endif + +#endif diff --git a/include/linux/qpnp/pwm.h b/include/linux/qpnp/pwm.h new file mode 100644 index 000000000000..50fb2e52a225 --- /dev/null +++ b/include/linux/qpnp/pwm.h @@ -0,0 +1,184 @@ +/* Copyright (c) 2012-2013, The Linux Foundation. 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 version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef __QPNP_PWM_H__ +#define __QPNP_PWM_H__ + +#include <linux/pwm.h> + +/* usec: 19.2M, n=6, m=0, pre=2 */ +#define PM_PWM_PERIOD_MIN 7 +/* 1K, n=9, m=7, pre=6 */ +#define PM_PWM_PERIOD_MAX (384 * USEC_PER_SEC) +#define PM_PWM_LUT_RAMP_STEP_TIME_MAX 499 +#define PM_PWM_MAX_PAUSE_CNT 8191 +/* + * Formula from HSID, + * pause_time (hi/lo) = (pause_code - 1)*(duty_ms) + */ +#define PM_PWM_LUT_PAUSE_MAX \ + ((PM_PWM_MAX_PAUSE_CNT - 1) * PM_PWM_LUT_RAMP_STEP_TIME_MAX) /* ms */ + +/* Flags for Look Up Table */ +#define PM_PWM_LUT_LOOP 0x01 +#define PM_PWM_LUT_RAMP_UP 0x02 +#define PM_PWM_LUT_REVERSE 0x04 +#define PM_PWM_LUT_PAUSE_HI_EN 0x08 +#define PM_PWM_LUT_PAUSE_LO_EN 0x10 + +#define PM_PWM_LUT_NO_TABLE 0x20 +#define PM_PWM_LUT_USE_RAW_VALUE 0x40 + +/* + * PWM frequency/period control + * + * PWM Frequency = ClockFrequency / (N * T) + * or + * PWM Period = Clock Period * (N * T) + * where + * N = 2^9 or 2^6 for 9-bit or 6-bit PWM size + * T = Pre-divide * 2^m, m = 0..7 (exponent) + */ + +/* + * enum pm_pwm_size - PWM bit mode selection + * %PM_PWM_SIZE_6BIT - Select 6 bit mode; 64 levels + * %PM_PWM_SIZE_9BIT - Select 9 bit mode; 512 levels + */ +enum pm_pwm_size { + PM_PWM_SIZE_6BIT = 6, + PM_PWM_SIZE_9BIT = 9, +}; + +/* + * enum pm_pwm_clk - PWM clock selection + * %PM_PWM_CLK_1KHZ - 1KHz clock + * %PM_PWM_CLK_32KHZ - 32KHz clock + * %PM_PWM_CLK_19P2MHZ - 19.2MHz clock + * Note: Here 1KHz = 1024Hz + */ +enum pm_pwm_clk { + PM_PWM_CLK_1KHZ, + PM_PWM_CLK_32KHZ, + PM_PWM_CLK_19P2MHZ, +}; + +/* PWM pre-divider selection */ +enum pm_pwm_pre_div { + PM_PWM_PDIV_2, + PM_PWM_PDIV_3, + PM_PWM_PDIV_5, + PM_PWM_PDIV_6, +}; + +/* + * struct pwm_period_config - PWM period configuration + * @pwm_size: enum pm_pwm_size + * @clk: enum pm_pwm_clk + * @pre_div: enum pm_pwm_pre_div + * @pre_div_exp: exponent of 2 as part of pre-divider: 0..7 + */ +struct pwm_period_config { + enum pm_pwm_size pwm_size; + enum pm_pwm_clk clk; + enum pm_pwm_pre_div pre_div; + int pre_div_exp; +}; + +/* + * struct pwm_duty_cycles - PWM duty cycle info + * duty_pcts - pointer to an array of duty percentage for a pwm period + * num_duty_pcts - total entries in duty_pcts array + * duty_ms - duty cycle time in ms + * start_idx - index in the LUT + */ +struct pwm_duty_cycles { + int *duty_pcts; + int num_duty_pcts; + int duty_ms; + int start_idx; +}; + +int pwm_config_period(struct pwm_device *pwm, + struct pwm_period_config *pwm_p); + +int pwm_config_pwm_value(struct pwm_device *pwm, int pwm_value); + +/* + * enum pm_pwm_mode - PWM mode selection + * %PM_PWM_MODE_PWM - Select PWM mode + * %PM_PWM_MODE_LPG - Select LPG mode + */ +enum pm_pwm_mode { + PM_PWM_MODE_PWM, + PM_PWM_MODE_LPG, +}; + +int pwm_change_mode(struct pwm_device *pwm, enum pm_pwm_mode mode); + +/* + * lut_params: Lookup table (LUT) parameters + * @start_idx: start index in lookup table from 0 to MAX-1 + * @idx_len: number of index + * @pause_lo: pause time in millisecond at low index + * @pause_hi: pause time in millisecond at high index + * @ramp_step_ms: time before loading next LUT pattern in millisecond + * @flags: control flags + */ +struct lut_params { + int start_idx; + int idx_len; + int lut_pause_hi; + int lut_pause_lo; + int ramp_step_ms; + int flags; +}; + +int pwm_lut_config(struct pwm_device *pwm, int period_us, + int duty_pct[], struct lut_params lut_params); + +/* + * support microsecond level configuration + */ +int pwm_config_us(struct pwm_device *pwm, + int duty_us, int period_us); + +/* Standard APIs supported */ +/* + * pwm_request - request a PWM device + * @pwm_id: PWM id or channel + * @label: the label to identify the user + */ + +/* + * pwm_free - free a PWM device + * @pwm: the PWM device + */ + +/* + * pwm_config - change a PWM device configuration + * @pwm: the PWM device + * @period_ns: period in nanosecond + * @duty_ns: duty cycle in nanosecond + */ + +/* + * pwm_enable - start a PWM output toggling + * @pwm: the PWM device + */ + +/* + * pwm_disable - stop a PWM output toggling + * @pwm: the PWM device + */ + +#endif /* __QPNP_PWM_H__ */ diff --git a/include/linux/reboot.h b/include/linux/reboot.h index 67fc8fcdc4b0..c9c38aa25ac5 100644 --- a/include/linux/reboot.h +++ b/include/linux/reboot.h @@ -34,7 +34,6 @@ extern int reboot_default; extern int reboot_cpu; extern int reboot_force; - extern int register_reboot_notifier(struct notifier_block *); extern int unregister_reboot_notifier(struct notifier_block *); diff --git a/include/linux/regulator/consumer.h b/include/linux/regulator/consumer.h index d17e1ff7ad01..d219c5bb7d26 100644 --- a/include/linux/regulator/consumer.h +++ b/include/linux/regulator/consumer.h @@ -36,6 +36,8 @@ #define __LINUX_REGULATOR_CONSUMER_H_ #include <linux/err.h> +#include <linux/types.h> +#include <linux/compiler.h> struct device; struct notifier_block; @@ -142,6 +144,10 @@ struct regulator; * using the bulk regulator APIs. * @consumer: The regulator consumer for the supply. This will be managed * by the bulk API. + * @min_uV: The minimum requested voltage for the regulator (in microvolts), + * or 0 to not set a voltage. + * @max_uV: The maximum requested voltage for the regulator (in microvolts), + * or 0 to use @min_uV. * * The regulator APIs provide a series of regulator_bulk_() API calls as * a convenience to consumers which require multiple supplies. This @@ -150,6 +156,8 @@ struct regulator; struct regulator_bulk_data { const char *supply; struct regulator *consumer; + int min_uV; + int max_uV; /* private: Internal use */ int ret; @@ -214,6 +222,8 @@ int __must_check devm_regulator_bulk_get(struct device *dev, int num_consumers, struct regulator_bulk_data *consumers); int __must_check regulator_bulk_enable(int num_consumers, struct regulator_bulk_data *consumers); +int regulator_bulk_set_voltage(int num_consumers, + struct regulator_bulk_data *consumers); int regulator_bulk_disable(int num_consumers, struct regulator_bulk_data *consumers); int regulator_bulk_force_disable(int num_consumers, diff --git a/include/linux/regulator/cpr-regulator.h b/include/linux/regulator/cpr-regulator.h new file mode 100644 index 000000000000..e49bc86707f1 --- /dev/null +++ b/include/linux/regulator/cpr-regulator.h @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2013-2014, The Linux Foundation. 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 version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef __REGULATOR_CPR_REGULATOR_H__ +#define __REGULATOR_CPR_REGULATOR_H__ + +#include <linux/regulator/machine.h> + +#define CPR_REGULATOR_DRIVER_NAME "qcom,cpr-regulator" + +/** + * enum cpr_fuse_corner_enum - CPR fuse corner enum values + * %CPR_FUSE_CORNER_SVS: Lowest voltage for APC + * %CPR_FUSE_CORNER_NORMAL: Normal mode voltage + * %CPR_FUSE_CORNER_TURBO: Turbo mode voltage + * %CPR_FUSE_CORNER_SUPER_TURBO: Super Turbo mode voltage + * + * These should be used in regulator_set_voltage() for CPR + * regulator as if they had units of uV. + */ +enum cpr_fuse_corner_enum { + CPR_FUSE_CORNER_SVS = 1, + CPR_FUSE_CORNER_NORMAL, + CPR_FUSE_CORNER_TURBO, + CPR_FUSE_CORNER_MAX, +}; + +/** + * enum vdd_mx_vmin_method - Method to determine vmin for vdd-mx + * %VDD_MX_VMIN_APC: Equal to APC voltage + * %VDD_MX_VMIN_APC_CORNER_CEILING: Equal to PVS corner ceiling voltage + * %VDD_MX_VMIN_APC_SLOW_CORNER_CEILING: + * Equal to slow speed corner ceiling + * %VDD_MX_VMIN_MX_VMAX: Equal to specified vdd-mx-vmax voltage + * %VDD_MX_VMIN_APC_CORNER_MAP: Equal to the APC corner mapped MX + * voltage + */ +enum vdd_mx_vmin_method { + VDD_MX_VMIN_APC, + VDD_MX_VMIN_APC_CORNER_CEILING, + VDD_MX_VMIN_APC_SLOW_CORNER_CEILING, + VDD_MX_VMIN_MX_VMAX, + VDD_MX_VMIN_APC_CORNER_MAP, +}; + +#ifdef CONFIG_REGULATOR_CPR + +int __init cpr_regulator_init(void); + +#else + +static inline int __init cpr_regulator_init(void) +{ + return -ENODEV; +} + +#endif /* CONFIG_REGULATOR_CPR */ + +#endif /* __REGULATOR_CPR_REGULATOR_H__ */ diff --git a/include/linux/regulator/krait-regulator.h b/include/linux/regulator/krait-regulator.h new file mode 100644 index 000000000000..10d7e2675f8f --- /dev/null +++ b/include/linux/regulator/krait-regulator.h @@ -0,0 +1,39 @@ +/* Copyright (c) 2012-2013, The Linux Foundation. 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 version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef __KRAIT_REGULATOR_H__ +#define __KRAIT_REGULATOR_H__ + +#define KRAIT_REGULATOR_DRIVER_NAME "krait-power-regulator" +#define KRAIT_PDN_DRIVER_NAME "krait-pdn" + +/** + * krait_power_init - driver initialization function + * + * This function registers the krait-power-regulator platform driver. This + * should be called from appropriate initialization code. Returns 0 on + * success and error on failure. + */ + +#ifdef CONFIG_KRAIT_REGULATOR +int __init krait_power_init(void); +void secondary_cpu_hs_init(void *base_ptr, int cpu); +#else +static inline int __init krait_power_init(void) +{ + return -ENOSYS; +} + +static inline void secondary_cpu_hs_init(void *base_ptr, int cpu) {} +#endif + +#endif diff --git a/include/linux/regulator/machine.h b/include/linux/regulator/machine.h index 0b08d05d470b..f144748f3f9b 100644 --- a/include/linux/regulator/machine.h +++ b/include/linux/regulator/machine.h @@ -196,10 +196,20 @@ int regulator_suspend_finish(void); #ifdef CONFIG_REGULATOR void regulator_has_full_constraints(void); +void regulator_use_dummy_regulator(void); +void regulator_suppress_info_printing(void); #else static inline void regulator_has_full_constraints(void) { } + +static inline void regulator_use_dummy_regulator(void) +{ +} + +static inline void regulator_suppress_info_printing(void) +{ +} #endif #endif diff --git a/include/linux/regulator/qpnp-regulator.h b/include/linux/regulator/qpnp-regulator.h new file mode 100644 index 000000000000..c7afeb50f244 --- /dev/null +++ b/include/linux/regulator/qpnp-regulator.h @@ -0,0 +1,197 @@ +/* + * Copyright (c) 2012-2013, The Linux Foundation. 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 version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef __REGULATOR_QPNP_REGULATOR_H__ +#define __REGULATOR_QPNP_REGULATOR_H__ + +#include <linux/regulator/machine.h> + +#define QPNP_REGULATOR_DRIVER_NAME "qcom,qpnp-regulator" + +/* Pin control enable input pins. */ +#define QPNP_REGULATOR_PIN_CTRL_ENABLE_NONE 0x00 +#define QPNP_REGULATOR_PIN_CTRL_ENABLE_EN0 0x01 +#define QPNP_REGULATOR_PIN_CTRL_ENABLE_EN1 0x02 +#define QPNP_REGULATOR_PIN_CTRL_ENABLE_EN2 0x04 +#define QPNP_REGULATOR_PIN_CTRL_ENABLE_EN3 0x08 +#define QPNP_REGULATOR_PIN_CTRL_ENABLE_HW_DEFAULT 0x10 + +/* Pin control high power mode input pins. */ +#define QPNP_REGULATOR_PIN_CTRL_HPM_NONE 0x00 +#define QPNP_REGULATOR_PIN_CTRL_HPM_EN0 0x01 +#define QPNP_REGULATOR_PIN_CTRL_HPM_EN1 0x02 +#define QPNP_REGULATOR_PIN_CTRL_HPM_EN2 0x04 +#define QPNP_REGULATOR_PIN_CTRL_HPM_EN3 0x08 +#define QPNP_REGULATOR_PIN_CTRL_HPM_SLEEP_B 0x10 +#define QPNP_REGULATOR_PIN_CTRL_HPM_HW_DEFAULT 0x20 + +/* + * Used with enable parameters to specify that hardware default register values + * should be left unaltered. + */ +#define QPNP_REGULATOR_DISABLE 0 +#define QPNP_REGULATOR_ENABLE 1 +#define QPNP_REGULATOR_USE_HW_DEFAULT 2 + +/* Soft start strength of a voltage switch type regulator */ +enum qpnp_vs_soft_start_str { + QPNP_VS_SOFT_START_STR_0P05_UA, + QPNP_VS_SOFT_START_STR_0P25_UA, + QPNP_VS_SOFT_START_STR_0P55_UA, + QPNP_VS_SOFT_START_STR_0P75_UA, + QPNP_VS_SOFT_START_STR_HW_DEFAULT, +}; + +/* Current limit of a boost type regulator */ +enum qpnp_boost_current_limit { + QPNP_BOOST_CURRENT_LIMIT_300_MA, + QPNP_BOOST_CURRENT_LIMIT_600_MA, + QPNP_BOOST_CURRENT_LIMIT_900_MA, + QPNP_BOOST_CURRENT_LIMIT_1200_MA, + QPNP_BOOST_CURRENT_LIMIT_1500_MA, + QPNP_BOOST_CURRENT_LIMIT_1800_MA, + QPNP_BOOST_CURRENT_LIMIT_2100_MA, + QPNP_BOOST_CURRENT_LIMIT_2400_MA, + QPNP_BOOST_CURRENT_LIMIT_HW_DEFAULT, +}; + +/** + * struct qpnp_regulator_platform_data - qpnp-regulator initialization data + * @init_data: regulator constraints + * @pull_down_enable: 1 = Enable output pull down resistor when the + * regulator is disabled + * 0 = Disable pull down resistor + * QPNP_REGULATOR_USE_HW_DEFAULT = do not modify + * pull down state + * @pin_ctrl_enable: Bit mask specifying which hardware pins should be + * used to enable the regulator, if any + * Value should be an ORing of + * QPNP_REGULATOR_PIN_CTRL_ENABLE_* constants. If + * the bit specified by + * QPNP_REGULATOR_PIN_CTRL_ENABLE_HW_DEFAULT is + * set, then pin control enable hardware registers + * will not be modified. + * @pin_ctrl_hpm: Bit mask specifying which hardware pins should be + * used to force the regulator into high power + * mode, if any + * Value should be an ORing of + * QPNP_REGULATOR_PIN_CTRL_HPM_* constants. If + * the bit specified by + * QPNP_REGULATOR_PIN_CTRL_HPM_HW_DEFAULT is + * set, then pin control mode hardware registers + * will not be modified. + * @system_load: Load in uA present on regulator that is not captured + * by any consumer request + * @enable_time: Time in us to delay after enabling the regulator + * @ocp_enable: 1 = Allow over current protection (OCP) to be + * enabled for voltage switch type regulators so + * that they latch off automatically when over + * current is detected. OCP is enabled when in HPM + * or auto mode. + * 0 = Disable OCP + * QPNP_REGULATOR_USE_HW_DEFAULT = do not modify + * OCP state + * @ocp_irq: IRQ number of the voltage switch OCP IRQ. If + * specified the voltage switch will be toggled off + * and back on when OCP triggers in order to handle + * high in-rush current. + * @ocp_max_retries: Maximum number of times to try toggling a voltage + * switch off and back on as a result of + * consecutive over current events. + * @ocp_retry_delay_ms: Time to delay in milliseconds between each + * voltage switch toggle after an over current + * event takes place. + * @boost_current_limit: This parameter sets the current limit of boost type + * regulators. Its value should be one of + * QPNP_BOOST_CURRENT_LIMIT_*. If its value is + * QPNP_BOOST_CURRENT_LIMIT_HW_DEFAULT, then the + * boost current limit will be left at its default + * hardware value. + * @soft_start_enable: 1 = Enable soft start for LDO and voltage switch + * type regulators so that output voltage slowly + * ramps up when the regulator is enabled + * 0 = Disable soft start + * QPNP_REGULATOR_USE_HW_DEFAULT = do not modify + * soft start state + * @vs_soft_start_strength: This parameter sets the soft start strength for + * voltage switch type regulators. Its value + * should be one of QPNP_VS_SOFT_START_STR_*. If + * its value is QPNP_VS_SOFT_START_STR_HW_DEFAULT, + * then the soft start strength will be left at its + * default hardware value. + * @auto_mode_enable: 1 = Enable automatic hardware selection of regulator + * mode (HPM vs LPM). Auto mode is not available + * on boost type regulators + * 0 = Disable auto mode selection + * QPNP_REGULATOR_USE_HW_DEFAULT = do not modify + * auto mode state + * @bypass_mode_enable: 1 = Enable bypass mode for an LDO type regulator so + * that it acts like a switch and simply outputs + * its input voltage + * 0 = Do not enable bypass mode + * QPNP_REGULATOR_USE_HW_DEFAULT = do not modify + * bypass mode state + * @hpm_enable: 1 = Enable high power mode (HPM), also referred to + * as NPM. HPM consumes more ground current than + * LPM, but it can source significantly higher load + * current. HPM is not available on boost type + * regulators. For voltage switch type regulators, + * HPM implies that over current protection and + * soft start are active all the time. This + * configuration can be overwritten by changing the + * regulator's mode dynamically. + * 0 = Do not enable HPM + * QPNP_REGULATOR_USE_HW_DEFAULT = do not modify + * HPM state + * @base_addr: SMPI base address for the regulator peripheral + */ +struct qpnp_regulator_platform_data { + struct regulator_init_data init_data; + int pull_down_enable; + unsigned pin_ctrl_enable; + unsigned pin_ctrl_hpm; + int system_load; + int enable_time; + int ocp_enable; + int ocp_irq; + int ocp_max_retries; + int ocp_retry_delay_ms; + enum qpnp_boost_current_limit boost_current_limit; + int soft_start_enable; + enum qpnp_vs_soft_start_str vs_soft_start_strength; + int auto_mode_enable; + int bypass_mode_enable; + int hpm_enable; + u16 base_addr; +}; + +#ifdef CONFIG_REGULATOR_QPNP + +/** + * qpnp_regulator_init() - register spmi driver for qpnp-regulator + * + * This initialization function should be called in systems in which driver + * registration ordering must be controlled precisely. + */ +int __init qpnp_regulator_init(void); + +#else + +static inline int __init qpnp_regulator_init(void) +{ + return -ENODEV; +} + +#endif /* CONFIG_REGULATOR_QPNP */ + +#endif diff --git a/include/linux/regulator/rpm-smd-regulator.h b/include/linux/regulator/rpm-smd-regulator.h new file mode 100644 index 000000000000..139030cd1eae --- /dev/null +++ b/include/linux/regulator/rpm-smd-regulator.h @@ -0,0 +1,108 @@ +/* Copyright (c) 2012-2013, The Linux Foundation. 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 version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _LINUX_REGULATOR_RPM_SMD_H +#define _LINUX_REGULATOR_RPM_SMD_H + +#include <linux/device.h> + +struct rpm_regulator; + +/** + * enum rpm_regulator_voltage_corner - possible voltage corner values + * + * These should be used in regulator_set_voltage() and + * rpm_regulator_set_voltage() calls for corner type regulators as if they had + * units of uV. + * + * Note, the meaning of corner values is set by the RPM. It is possible that + * future platforms will utilize different corner values. The values specified + * in this enum correspond to MSM8974 for PMIC PM8841 SMPS 2 (VDD_Dig). + */ +enum rpm_regulator_voltage_corner { + RPM_REGULATOR_CORNER_NONE = 1, + RPM_REGULATOR_CORNER_RETENTION, + RPM_REGULATOR_CORNER_SVS_KRAIT, + RPM_REGULATOR_CORNER_SVS_SOC, + RPM_REGULATOR_CORNER_NORMAL, + RPM_REGULATOR_CORNER_TURBO, + RPM_REGULATOR_CORNER_SUPER_TURBO, +}; + +/** + * enum rpm_regulator_mode - control mode for LDO or SMPS type regulators + * %RPM_REGULATOR_MODE_AUTO: For SMPS type regulators, use SMPS auto mode so + * that the hardware can automatically switch + * between PFM and PWM modes based on realtime + * load. + * LDO type regulators do not support this mode. + * %RPM_REGULATOR_MODE_IPEAK: For SMPS type regulators, use aggregated + * software current requests to determine + * usage of PFM or PWM mode. + * For LDO type regulators, use aggregated + * software current requests to determine + * usage of LPM or HPM mode. + * %RPM_REGULATOR_MODE_HPM: For SMPS type regulators, force the + * usage of PWM mode. + * For LDO type regulators, force the + * usage of HPM mode. + * + * These values should be used in calls to rpm_regulator_set_mode(). + */ +enum rpm_regulator_mode { + RPM_REGULATOR_MODE_AUTO, + RPM_REGULATOR_MODE_IPEAK, + RPM_REGULATOR_MODE_HPM, +}; + +#ifdef CONFIG_REGULATOR_RPM_SMD + +struct rpm_regulator *rpm_regulator_get(struct device *dev, const char *supply); + +void rpm_regulator_put(struct rpm_regulator *regulator); + +int rpm_regulator_enable(struct rpm_regulator *regulator); + +int rpm_regulator_disable(struct rpm_regulator *regulator); + +int rpm_regulator_set_voltage(struct rpm_regulator *regulator, int min_uV, + int max_uV); + +int rpm_regulator_set_mode(struct rpm_regulator *regulator, + enum rpm_regulator_mode mode); + +int __init rpm_smd_regulator_driver_init(void); + +#else + +static inline struct rpm_regulator *rpm_regulator_get(struct device *dev, + const char *supply) { return NULL; } + +static inline void rpm_regulator_put(struct rpm_regulator *regulator) { } + +static inline int rpm_regulator_enable(struct rpm_regulator *regulator) + { return 0; } + +static inline int rpm_regulator_disable(struct rpm_regulator *regulator) + { return 0; } + +static inline int rpm_regulator_set_voltage(struct rpm_regulator *regulator, + int min_uV, int max_uV) { return 0; } + +static inline int rpm_regulator_set_mode(struct rpm_regulator *regulator, + enum rpm_regulator_mode mode) { return 0; } + +static inline int __init rpm_smd_regulator_driver_init(void) { return 0; } + +#endif /* CONFIG_REGULATOR_RPM_SMD */ + +#endif diff --git a/include/linux/regulator/spm-regulator.h b/include/linux/regulator/spm-regulator.h new file mode 100644 index 000000000000..bd5da2e3352b --- /dev/null +++ b/include/linux/regulator/spm-regulator.h @@ -0,0 +1,25 @@ +/* Copyright (c) 2013-2014, The Linux Foundation. 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 version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _LINUX_REGULATOR_SPM_H +#define _LINUX_REGULATOR_SPM_H + +#include <linux/err.h> +#include <linux/init.h> + +#ifdef CONFIG_REGULATOR_SPM +int __init spm_regulator_init(void); +#else +static inline int __init spm_regulator_init(void) { return -ENODEV; } +#endif + +#endif diff --git a/include/linux/regulator/stub-regulator.h b/include/linux/regulator/stub-regulator.h new file mode 100644 index 000000000000..1155d82ba27b --- /dev/null +++ b/include/linux/regulator/stub-regulator.h @@ -0,0 +1,54 @@ +/* Copyright (c) 2012, The Linux Foundation. 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 version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef __STUB_REGULATOR_H__ +#define __STUB_REGULATOR_H__ + +#include <linux/regulator/machine.h> + +#define STUB_REGULATOR_DRIVER_NAME "stub-regulator" + +/** + * struct stub_regulator_pdata - stub regulator device data + * @init_data: regulator constraints + * @hpm_min_load: minimum load in uA that will result in the regulator + * being set to high power mode + * @system_uA: current drawn from regulator not accounted for by any + * regulator framework consumer + */ +struct stub_regulator_pdata { + struct regulator_init_data init_data; + int hpm_min_load; + int system_uA; +}; + +#ifdef CONFIG_REGULATOR_STUB + +/** + * regulator_stub_init() - register platform driver for stub-regulator + * + * This initialization function should be called in systems in which driver + * registration ordering must be controlled precisely. + */ + +int __init regulator_stub_init(void); + +#else + +static inline int __init regulator_stub_init(void) +{ + return -ENODEV; +} + +#endif /* CONFIG_REGULATOR_STUB */ + +#endif diff --git a/include/linux/remote_spinlock.h b/include/linux/remote_spinlock.h new file mode 100644 index 000000000000..b1df5792ac78 --- /dev/null +++ b/include/linux/remote_spinlock.h @@ -0,0 +1,98 @@ +/* Copyright (c) 2008-2009, 2011, 2013-2014 The Linux Foundation. + * 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 version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ +#ifndef __LINUX_REMOTE_SPINLOCK_H +#define __LINUX_REMOTE_SPINLOCK_H + +#include <linux/spinlock.h> +#include <linux/msm_remote_spinlock.h> + +/* Grabbing a local spin lock before going for a remote lock has several + * advantages: + * 1. Get calls to preempt enable/disable and IRQ save/restore for free. + * 2. For UP kernel, there is no overhead. + * 3. Reduces the possibility of executing the remote spin lock code. This is + * especially useful when the remote CPUs' mutual exclusion instructions + * don't work with the local CPUs' instructions. In such cases, one has to + * use software based mutex algorithms (e.g. Lamport's bakery algorithm) + * which could get expensive when the no. of contending CPUs is high. + * 4. In the case of software based mutex algorithm the exection time will be + * smaller since the no. of contending CPUs is reduced by having just one + * contender for all the local CPUs. + * 5. Get most of the spin lock debug features for free. + * 6. The code will continue to work "gracefully" even when the remote spin + * lock code is stubbed out for debug purposes or when there is no remote + * CPU in some board/machine types. + */ +typedef struct { + spinlock_t local; + _remote_spinlock_t remote; +} remote_spinlock_t; + +#define remote_spin_lock_init(lock, id) \ + ({ \ + spin_lock_init(&((lock)->local)); \ + _remote_spin_lock_init(id, &((lock)->remote)); \ + }) +#define remote_spin_lock(lock) \ + do { \ + spin_lock(&((lock)->local)); \ + _remote_spin_lock(&((lock)->remote)); \ + } while (0) +#define remote_spin_unlock(lock) \ + do { \ + _remote_spin_unlock(&((lock)->remote)); \ + spin_unlock(&((lock)->local)); \ + } while (0) +#define remote_spin_lock_irqsave(lock, flags) \ + do { \ + spin_lock_irqsave(&((lock)->local), flags); \ + _remote_spin_lock(&((lock)->remote)); \ + } while (0) +#define remote_spin_unlock_irqrestore(lock, flags) \ + do { \ + _remote_spin_unlock(&((lock)->remote)); \ + spin_unlock_irqrestore(&((lock)->local), flags); \ + } while (0) +#define remote_spin_trylock(lock) \ + ({ \ + spin_trylock(&((lock)->local)) \ + ? _remote_spin_trylock(&((lock)->remote)) \ + ? 1 \ + : ({ spin_unlock(&((lock)->local)); 0; }) \ + : 0; \ + }) +#define remote_spin_trylock_irqsave(lock, flags) \ + ({ \ + spin_trylock_irqsave(&((lock)->local), flags) \ + ? _remote_spin_trylock(&((lock)->remote)) \ + ? 1 \ + : ({ spin_unlock_irqrestore(&((lock)->local), flags); \ + 0; }) \ + : 0; \ + }) +#define remote_spin_lock_rlock_id(lock, tid) \ + _remote_spin_lock_rlock_id(&((lock)->remote), tid) + +#define remote_spin_unlock_rlock(lock) \ + _remote_spin_unlock_rlock(&((lock)->remote)) + +#define remote_spin_release(lock, pid) \ + _remote_spin_release(&((lock)->remote), pid) + +#define remote_spin_release_all(pid) \ + _remote_spin_release_all(pid) + +#define remote_spin_owner(lock) \ + _remote_spin_owner(&((lock)->remote)) +#endif diff --git a/include/linux/sched.h b/include/linux/sched.h index 8db31ef98d2f..568731cbd6bc 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -3079,4 +3079,6 @@ static inline unsigned long rlimit_max(unsigned int limit) return task_rlimit_max(current, limit); } +extern void mm_init_owner(struct mm_struct *mm, struct task_struct *p); + #endif diff --git a/include/linux/sched_clock.h b/include/linux/sched_clock.h index efa931c5cef1..e10601e855c8 100644 --- a/include/linux/sched_clock.h +++ b/include/linux/sched_clock.h @@ -16,5 +16,10 @@ static inline void sched_clock_postinit(void) { } extern void sched_clock_register(u64 (*read)(void), int bits, unsigned long rate); +extern void setup_sched_clock(u32 (*read)(void), int bits, unsigned long rate); +extern void sched_clock_register(u64 (*read)(void), int bits, + unsigned long rate); + +extern unsigned long long (*sched_clock_func)(void); #endif diff --git a/include/linux/smp.h b/include/linux/smp.h index 93dff5fff524..6aaaddafd7a8 100644 --- a/include/linux/smp.h +++ b/include/linux/smp.h @@ -111,6 +111,27 @@ void generic_smp_call_function_single_interrupt(void); generic_smp_call_function_single_interrupt /* + * Call a function on all processors + */ +int on_each_cpu(smp_call_func_t func, void *info, int wait); + +/* + * Call a function on processors specified by mask, which might include + * the local one. + */ +void on_each_cpu_mask(const struct cpumask *mask, smp_call_func_t func, + void *info, bool wait); + +/* + * Call a function on each processor for which the supplied function + * cond_func returns a positive value. This may include the local + * processor. + */ +void on_each_cpu_cond(bool (*cond_func)(int cpu, void *info), + smp_call_func_t func, void *info, bool wait, + gfp_t gfp_flags); + +/* * Mark the boot cpu "online" so that it can call console drivers in * printk() and can access its per-cpu storage. */ diff --git a/include/linux/spmi.h b/include/linux/spmi.h index f84212cd3b7d..be22a46c5bc2 100644 --- a/include/linux/spmi.h +++ b/include/linux/spmi.h @@ -39,6 +39,28 @@ #define SPMI_CMD_ZERO_WRITE 0x80 /** + * * struct spmi_resource: spmi_resource for one device_node + * * @num_resources: number of resources for this device node + * * @resources: array of resources for this device_node + * * @of_node: device_node of the resource in question + * * @label: name used to reference the device from the driver + * * + * * Note that we explicitly add a 'label' pointer here since per + * * the ePAPR 2.2.2, the device_node->name should be generic and not + * * reflect precise programming model. Thus label enables a + * * platform specific name to be assigned with the 'label' binding to + * * allow for unique query names. + * */ +struct spmi_resource { + struct resource *resource; + u32 num_resources; + struct device_node *of_node; + const char *label; +}; + + + +/** * struct spmi_device - Basic representation of an SPMI device * @dev: Driver model representation of the device. * @ctrl: SPMI controller managing the bus hosting this device. @@ -48,6 +70,11 @@ struct spmi_device { struct device dev; struct spmi_controller *ctrl; u8 usid; + + const char *name; + struct spmi_resource res; + struct spmi_resource *dev_node; + u32 num_dev_node; }; static inline struct spmi_device *to_spmi_device(struct device *d) @@ -77,6 +104,7 @@ int spmi_device_add(struct spmi_device *sdev); void spmi_device_remove(struct spmi_device *sdev); + /** * struct spmi_controller - interface to the SPMI master controller * @dev: Driver model representation of the device. @@ -185,4 +213,50 @@ int spmi_command_sleep(struct spmi_device *sdev); int spmi_command_wakeup(struct spmi_device *sdev); int spmi_command_shutdown(struct spmi_device *sdev); +/** + * * spmi_for_each_container_dev - iterate over the array of devnode resources. + * * @res: spmi_resource pointer used as the array cursor + * * @spmi_dev: spmi_device to iterate + * * + * * Only useable in spmi-dev-container configurations. + * */ +#define spmi_for_each_container_dev(res, spmi_dev) \ + for (res = ((spmi_dev)->dev_node ? &(spmi_dev)->dev_node[0] : NULL); \ + (res - (spmi_dev)->dev_node) < (spmi_dev)->num_dev_node; res++) + +extern struct resource *spmi_get_resource(struct spmi_device *dev, + struct spmi_resource *node, + unsigned int type, unsigned int res_num); + +struct resource *spmi_get_resource_byname(struct spmi_device *dev, + struct spmi_resource *node, + unsigned int type, + const char *name); + +extern int spmi_get_irq(struct spmi_device *dev, struct spmi_resource *node, + unsigned int res_num); + +extern int spmi_get_irq_byname(struct spmi_device *dev, + struct spmi_resource *node, const char *name); + +/** + * * spmi_get_node_name - return device name for spmi node + * * @dev: spmi device handle + * * + * * Get the primary node name of a spmi_device coresponding with + * * with the 'label' binding. + * * + * * Returns NULL if no primary dev name has been assigned to this spmi_device. + * */ +static inline const char *spmi_get_primary_dev_name(struct spmi_device *dev) +{ + if (dev->res.label) + return dev->res.label; + return NULL; +} + +struct spmi_resource *spmi_get_dev_container_byname(struct spmi_device *dev, + const char *label); + + #endif diff --git a/include/linux/topology.h b/include/linux/topology.h index 909b6e43b694..0526d2449749 100644 --- a/include/linux/topology.h +++ b/include/linux/topology.h @@ -67,6 +67,115 @@ int arch_update_cpu_topology(void); #define PENALTY_FOR_NODE_WITH_CPUS (1) #endif +/* + * Below are the 3 major initializers used in building sched_domains: + * SD_SIBLING_INIT, for SMT domains + * SD_CPU_INIT, for SMP domains + * + * Any architecture that cares to do any tuning to these values should do so + * by defining their own arch-specific initializer in include/asm/topology.h. + * A definition there will automagically override these default initializers + * and allow arch-specific performance tuning of sched_domains. + * (Only non-zero and non-null fields need be specified.) + */ + +#ifdef CONFIG_SCHED_SMT +/* MCD - Do we really need this? It is always on if CONFIG_SCHED_SMT is, + * so can't we drop this in favor of CONFIG_SCHED_SMT? + */ +#define ARCH_HAS_SCHED_WAKE_IDLE +/* Common values for SMT siblings */ +#ifndef SD_SIBLING_INIT +#define SD_SIBLING_INIT (struct sched_domain) { \ + .min_interval = 1, \ + .max_interval = 2, \ + .busy_factor = 64, \ + .imbalance_pct = 110, \ + \ + .flags = 1*SD_LOAD_BALANCE \ + | 1*SD_BALANCE_NEWIDLE \ + | 1*SD_BALANCE_EXEC \ + | 1*SD_BALANCE_FORK \ + | 0*SD_BALANCE_WAKE \ + | 1*SD_WAKE_AFFINE \ + | 1*SD_SHARE_CPUPOWER \ + | 1*SD_SHARE_PKG_RESOURCES \ + | 0*SD_SERIALIZE \ + | 0*SD_PREFER_SIBLING \ + | arch_sd_sibling_asym_packing() \ + , \ + .last_balance = jiffies, \ + .balance_interval = 1, \ + .smt_gain = 1178, /* 15% */ \ +} +#endif +#endif /* CONFIG_SCHED_SMT */ + +#ifdef CONFIG_SCHED_MC +/* Common values for MC siblings. for now mostly derived from SD_CPU_INIT */ +#ifndef SD_MC_INIT +#define SD_MC_INIT (struct sched_domain) { \ + .min_interval = 1, \ + .max_interval = 4, \ + .busy_factor = 1, \ + .imbalance_pct = 125, \ + .cache_nice_tries = 1, \ + .busy_idx = 2, \ + .wake_idx = 0, \ + .forkexec_idx = 0, \ + \ + .flags = 1*SD_LOAD_BALANCE \ + | 1*SD_BALANCE_NEWIDLE \ + | 1*SD_BALANCE_EXEC \ + | 1*SD_BALANCE_FORK \ + | 0*SD_BALANCE_WAKE \ + | 1*SD_WAKE_AFFINE \ + | 0*SD_SHARE_CPUPOWER \ + | 1*SD_SHARE_PKG_RESOURCES \ + | 0*SD_SERIALIZE \ + , \ + .last_balance = jiffies, \ + .balance_interval = 1, \ +} +#endif +#endif /* CONFIG_SCHED_MC */ + +/* Common values for CPUs */ +#ifndef SD_CPU_INIT +#define SD_CPU_INIT (struct sched_domain) { \ + .min_interval = 1, \ + .max_interval = 4, \ + .busy_factor = 64, \ + .imbalance_pct = 125, \ + .cache_nice_tries = 1, \ + .busy_idx = 2, \ + .idle_idx = 1, \ + .newidle_idx = 0, \ + .wake_idx = 0, \ + .forkexec_idx = 0, \ + \ + .flags = 1*SD_LOAD_BALANCE \ + | 1*SD_BALANCE_NEWIDLE \ + | 1*SD_BALANCE_EXEC \ + | 1*SD_BALANCE_FORK \ + | 0*SD_BALANCE_WAKE \ + | 1*SD_WAKE_AFFINE \ + | 0*SD_SHARE_CPUPOWER \ + | 1*SD_SHARE_PKG_RESOURCES \ + | 0*SD_SERIALIZE \ + | 1*SD_PREFER_SIBLING \ + , \ + .last_balance = jiffies, \ + .balance_interval = 1, \ +} +#endif + +#ifdef CONFIG_SCHED_BOOK +#ifndef SD_BOOK_INIT +#error Please define an appropriate SD_BOOK_INIT in include/asm/topology.h!!! +#endif +#endif /* CONFIG_SCHED_BOOK */ + #ifdef CONFIG_USE_PERCPU_NUMA_NODE_ID DECLARE_PER_CPU(int, numa_node); |